题目链接:

  http://codeforces.com/problemset/problem/691/D

题目大意:

  给一个1到N的排列,M个操作(1<=N,M<=106),每个操作可以交换X Y位置上的数字,求可以得到的最大字典序的数列。

题目思路:

  【搜索】【并查集】

  这题可以用搜索或者并查集写,都能过。

  把位置分成若干块,每一块里面的位置都是可以被这一块里另一个位置经过若干次调换的(类似强连通,位置可达)。

  然后把每一块位置里的 位置按从小到大排序,位置上的值按从大到小排序,依次填入位置(最大的放最前)。

  每个点都会被放且仅放一次。

并查集:

 //
//by coolxxx
//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<bitset>
#include<memory.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#include<stdbool.h>
#include<math.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define eps (1e-8)
#define J 10
#define mod 1000000007
#define MAX 0x7f7f7f7f
#define PI 3.14159265358979323
#define N 1000004
using namespace std;
typedef long long LL;
int cas,cass;
int n,m,lll,ans;
int fa[N],next[N],last[N],c[N],a[N],b[N],d[N];
bool mark[N];
int zhao(int aa)
{
if(fa[aa]== || fa[aa]==aa)return aa;
return fa[aa]=zhao(fa[aa]);
}
bool cmp1(int aa,int bb)
{
return aa>bb;
}
bool cmp2(int aa,int bb)
{
return aa<bb;
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
#endif
int i,j,k;
int x,y,fx,fy;
// for(scanf("%d",&cass);cass;cass--)
// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
// while(~scanf("%s",s+1))
while(~scanf("%d",&n))
{
mem(last,);mem(mark,);mem(fa,);
scanf("%d",&m);
for(i=;i<=n;i++)
scanf("%d",c+i);
for(i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
fx=zhao(x);
fy=zhao(y);
fa[fy]=fx;
}
for(i=;i<=n;i++)
{
fa[i]=zhao(i);
next[i]=last[fa[i]],last[fa[i]]=i;
}
for(i=;i<=n;i++)
{
if(mark[c[i]])continue;
for(k=,j=last[fa[i]];j;j=next[j])
{
a[++k]=c[j];
b[k]=j;
}
sort(a+,a++k,cmp1);
sort(b+,b++k,cmp2);
for(j=;j<=k;j++)
d[b[j]]=a[j],mark[a[j]]=;
}
for(i=;i<=n;i++)
printf("%d ",d[i]);
puts("");
}
return ;
}
/*
// //
*/

搜索(学长写的):

 #include<stdio.h>
#include<algorithm>
#define MAXN 1000002
using namespace std; int a[MAXN],first[MAXN],to[*MAXN],next[*MAXN];
int stack_a[MAXN],stack_loc[MAXN],ans[MAXN];
bool vis[MAXN];
int top; void dfs(int u)
{
int e,v; vis[u]=true;
stack_a[top]=a[u];
stack_loc[top++]=u;
e=first[u];
while(e)
{
v=to[e];
if(!vis[v])dfs(v);
e=next[e];
}
} int main()
{
int n,m,i,j,u,v; scanf("%d%d",&n,&m);
for(i=;i<=n;i++)scanf("%d",&a[i]);
for(i=;i<=m;i++)
{
scanf("%d%d",&u,&v);
next[i]=first[u];
next[i+m]=first[v];
first[u]=i;
first[v]=i+m;
to[i]=v;
to[i+m]=u;
}
for(i=;i<=n;i++)
{
if(!vis[i])
{
top=;
dfs(i);
sort(stack_a,stack_a+top);
sort(stack_loc,stack_loc+top);
for(j=;j<top;j++)ans[stack_loc[j]]=stack_a[top-j-];
}
}
for(i=;i<=n;i++)
{
printf("%d",ans[i]);
printf("%c",i<n?' ':'\n');
} return ;
}

【搜索】【并查集】Codeforces 691D Swaps in Permutation的更多相关文章

  1. Codeforces 691D Swaps in Permutation

    Time Limit:5000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Prac ...

  2. codeforces 691D Swaps in Permutation DFS

    这个题刚开始我以为是每个交换只能用一次,然后一共m次操作 结果这个题的意思是操作数目不限,每个交换也可以无限次 所以可以交换的两个位置连边,只要两个位置连通,就可以呼唤 然后连通块内排序就好了 #in ...

  3. 贪心+bfs 或者 并查集 Codeforces Round #268 (Div. 2) D

    http://codeforces.com/contest/469/problem/D 题目大意: 给你一个长度为n数组,给你两个集合A.B,再给你两个数字a和b.A集合中的每一个数字x都也能在a集合 ...

  4. DFS/并查集 Codeforces Round #286 (Div. 2) B - Mr. Kitayuta's Colorful Graph

    题目传送门 /* 题意:两点之间有不同颜色的线连通,问两点间单一颜色连通的路径有几条 DFS:暴力每个颜色,以u走到v为结束标志,累加条数 注意:无向图 */ #include <cstdio& ...

  5. 01背包dp+并查集 Codeforces Round #383 (Div. 2)

    http://codeforces.com/contest/742/problem/D 题目大意:有n个人,每个人有重量wi和魅力值bi.然后又有m对朋友关系,朋友关系是传递的,如果a和b是朋友,b和 ...

  6. CodeForces 691D:Swaps in Permutation(并查集)

    http://codeforces.com/contest/691/problem/D D. Swaps in Permutation   You are given a permutation of ...

  7. Educational Codeforces Round 14 D. Swaps in Permutation 并查集

    D. Swaps in Permutation 题目连接: http://www.codeforces.com/contest/691/problem/D Description You are gi ...

  8. Educational Codeforces Round 14 D. Swaps in Permutation (并查集orDFS)

    题目链接:http://codeforces.com/problemset/problem/691/D 给你n个数,各不相同,范围是1到n.然后是m行数a和b,表示下标为a的数和下标为b的数可以交换无 ...

  9. Educational Codeforces Round 14 D. Swaps in Permutation(并查集)

    题目链接:http://codeforces.com/contest/691/problem/D 题意: 题目给出一段序列,和m条关系,你可以无限次互相交换这m条关系 ,问这条序列字典序最大可以为多少 ...

随机推荐

  1. angular应用前景

    完成了angularJs的学习,突然想到,angularJS是否会影响到seo.于是查阅了很多资料,技术博客,这种想法得到了证实. 爬虫不能识别js渲染的内容.所以引起了我对angular应用前景的思 ...

  2. ASP.NET如何发布更新

    如果一个应用程序迭代开发后,我们如何来进行发布更新呢? 这里,我用Visual Studio 2008和SQL server来演示. 一.程序修改完毕后,我们要进行以下操作: 1.1 点击解决方案,重 ...

  3. 网站如何防Session冒名顶替和cookie防篡改

    做网站难免要面对安全性的问题,诸如sql注入拉,cookie冒名拉,等等,sql注入算是老生常谈,翻翻旧账有不少优秀的帖子在说明这个问题,所以我们来说说Session冒名顶替的风险以及应对的办法. 首 ...

  4. 在使用Kettle的集群排序中 Carte的设定——(基于Windows)

    本片文章主要是关于使用Kettle的UI界面: Spoon来实现基于集群的对数据库中的数据表数据进行排序的试验. 以及在实验过程中所要开启的Carte服务的一些配置文件的设置, 还有基于Windows ...

  5. [转]关于java中的 sychronized 同步方法 与 同步块的理解

    首先,需要说明一点,也是最重要的一点,无论是同步方法 还是 同步块 都是只针对同一个对象的多线程而言的,只有同一个对象产生的多线程,才会考虑到 同步方法 或者是 同步块,如果定义多个实例的同步,可以考 ...

  6. 解读oracle执行计划-待续

    Cost(%CPU): 优化器估算出完成当前操作的代价(包含子操作的代价),它是IO代价和CPU 代价总和.其中IO代价是最基本的代价.而对于CPU代价,在默认情况下,优化器会将CPU代价计算在内,而 ...

  7. Objective-C和C++的区别

    1.都是有C语言延伸而来2.OC是完全动态的,C++是部分动态的3.OC不支持多继承,通过代理 类别 协议优雅的实现了相关的一系列特性4.调用机制不同OC里面叫发送消息  C++叫做调用函数数5.OC ...

  8. 安装SQLServer2008后Windows防火墙上的端口开放

    1.打开SQL Server 配置管理器-->SQL Server 网络配置-->XXX的协议,启用TCP/IP协议2.打开TCP/IP协议的属性,切至“IP地址”标签,拉至最下端的IPA ...

  9. java操作excel常用的两种方式

    Excel是我们平时工作中比较常用的用于存储二维表数据的,JAVA也可以直接对Excel进行操作,在这篇博客中将为大家介绍两种操作Excel的方式,分别为:jxl和poi. 对于两者的区别网上有测试如 ...

  10. Junit4_单元测试

    不多说,直接练习学习. 1.将Junit4单元测试包引入项目:项目右键——“属性”,选择“Java Build Path”,然后到右上选择“Libraries”标签,之后在最右边点击“Add Libr ...