题目链接: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 }
时间: 2024-10-23 19:32:53