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

题目链接:http://codeforces.com/problemset/problem/691/D

给你n个数,各不相同,范围是1到n。然后是m行数a和b,表示下标为a的数和下标为b的数可以交换无数次。问你最后字典序最大的数列是什么。

将下面的a和b用并查集联系起来存到祖节点对应的数组中,然后从大到小排序数组,最后依次按照父节点的数组中的顺序输出。

也可以用dfs的方法解(略麻烦),形成一个环路的就在一个数组中...

 1 //并查集
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 const int N = 1e6 + 5;
 5 vector <int> ans[N];
 6 vector <int> root;
 7 int pos[N] , par[N] , a[N] , vis[N];
 8 
 9 int Find(int n) {
10     if(n == par[n])
11         return n;
12     return par[n] = Find(par[n]);
13 }
14 
15 int main()
16 {
17     int n , m , u , v;
18     scanf("%d %d" , &n , &m);
19     for(int i = 1 ; i <= n ; ++i) {
20         scanf("%d" , a + i);
21         par[i] = i;
22     }
23     while(m--) {
24         scanf("%d %d" , &u , &v);
25         u = Find(u) , v = Find(v);
26         if(u != v)
27             par[u] = v;
28     }
29     for(int i = 1 ; i <= n ; ++i) {
30         int u = Find(i);
31         ans[u].push_back(a[i]);
32         if(!vis[u]) {
33             root.push_back(u);
34             vis[u] = true;
35         }
36     }
37     for(int i = 0 ; i < root.size() ; ++i)
38         sort(ans[root[i]].rbegin() , ans[root[i]].rend());
39     for(int i = 1 ; i < n ; ++i)
40         printf("%d " , ans[Find(i)][pos[Find(i)]++]);
41     printf("%d\n" , ans[Find(n)][pos[Find(n)]]);
42     return 0;
43 }
 1 //dfs
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 const int N = 1e6 + 5;
 5 struct Edge {
 6     int next , to;
 7 }edge[N << 1];
 8 vector <int> ans[N];
 9 vector <int> Root;
10 int a[N] , head[N] , cnt , is[N] , pos[N] , believe[N];
11 bool vis[N];
12 
13 inline void add(int u , int v) {
14     edge[cnt].next = head[u];
15     edge[cnt].to = v;
16     head[u] = cnt++;
17 }
18 
19 void dfs(int root , int u , int par) {
20     vis[u] = true;
21     is[u] = root;
22     ans[root].push_back(a[u]);
23     for(int i = head[u] ; ~i ; i = edge[i].next) {
24         int v = edge[i].to;
25         if(v == par || vis[v])
26             continue;
27         dfs(root , v , u);
28     }
29 }
30 
31 int main()
32 {
33     memset(head , -1 , sizeof(head));
34     int n , m , u , v;
35     scanf("%d %d" , &n , &m);
36     for(int i = 1 ; i <= n ; ++i)
37         scanf("%d" , a + i);
38     while(m--) {
39         scanf("%d %d" , &u , &v);
40         add(u , v);
41         add(v , u);
42     }
43     for(int i = 1 ; i <= n ; ++i) {
44         if(!vis[i]) {
45             Root.push_back(i);
46             believe[i] = Root.size() - 1;
47             dfs(i , i , -1);
48         }
49     }
50     for(int i = 0 ; i < Root.size() ; ++i) {
51         sort(ans[Root[i]].rbegin() , ans[Root[i]].rend());
52     }
53     for(int i = 1 ; i <= n ; ++i) {
54         printf("%d" , ans[ Root[believe[is[i]]] ][ pos[believe[is[i]]]++ ]);
55         if(i != n)
56             putchar(' ');
57         else
58             putchar('\n');
59     }
60     return 0;
61 }

 

posted @ 2016-07-14 21:19  Recoder  阅读(206)  评论(0编辑  收藏  举报