codeforces 691D Swaps in Permutation DFS

这个题刚开始我以为是每个交换只能用一次,然后一共m次操作

结果这个题的意思是操作数目不限,每个交换也可以无限次

所以可以交换的两个位置连边,只要两个位置连通,就可以呼唤

然后连通块内排序就好了

#include <vector>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;
const int N=1e6+5;
const LL mod=1e9+7;
struct Edge{
  int v,next;
}edge[N<<1];
int head[N],tot,a[N],n,m,cnt;
vector<int>bcc[N],ran[N];
void add(int u,int v){
  edge[tot].v=v;
  edge[tot].next=head[u];
  head[u]=tot++;
}
bool vis[N];
void dfs(int u){
  vis[u]=true;
  bcc[cnt].push_back(a[u]);
  ran[cnt].push_back(u);
  for(int i=head[u];~i;i=edge[i].next)
    if(!vis[edge[i].v])dfs(edge[i].v);
}
int main(){
   scanf("%d%d",&n,&m);
   for(int i=1;i<=n;++i)
    scanf("%d",&a[i]);
   memset(head,-1,sizeof(head));
   for(int i=1;i<=m;++i){
     int u,v;scanf("%d%d",&u,&v);
     add(u,v);add(v,u);
   }
  for(int i=1;i<=n;++i){
   if(vis[i])continue;
    ++cnt;dfs(i);
  }
  for(int i=1;i<=cnt;++i){
    sort(bcc[i].begin(),bcc[i].end());
    sort(ran[i].begin(),ran[i].end());
    int sz=bcc[i].size()-1;
    for(int j=0,k=sz;j<=sz;++j,--k)
      a[ran[i][j]]=bcc[i][k];
  }
  for(int i=1;i<n;++i)printf("%d ",a[i]);
    printf("%d
",a[n]);
  return 0;
}
View Code
原文地址:https://www.cnblogs.com/shuguangzw/p/5674294.html