wenbao与并查集(关于成环与联通)

Posted wenbao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wenbao与并查集(关于成环与联通)相关的知识,希望对你有一定的参考价值。

 
 
 1 #include <iostream>
 2 #include <string.h>
 3 using namespace std;
 4 const int maxn = 100010;
 5 int T[maxn];
 6 bool flag[maxn];
 7 void init(){
 8     for(int i=0; i<maxn; i++)    T[i]=i;
 9 }
10 int findn(int x){
11     return x==T[x]?x:T[x]=findn(T[x]);
12 }
13 int main(){
14     int a,b,circle;
15     init();
16     memset(flag,0,sizeof(flag));
17     circle=0;
18     while(cin>>a>>b){
19         if(a==-1&&b==-1)
20             break;
21         else if(a==0&&b==0){
22             flag[0]=1;
23             int unicom=0;
24             for(int i=0; i<maxn; i++){
25                 if(flag[i]&&T[i]==i)
26                     unicom++;
27             }
28             if(!circle&&unicom<=2)
29                 cout<<"Yes"<<endl;
30             else
31                 cout<<"No"<<endl;
32             init();
33             memset(flag,0,sizeof(flag));
34             circle=0;
35         }
36         else{
37             flag[a]=flag[b]=1;
38             int x=findn(a);
39             int y=findn(b);
40             if(x==y)
41                 circle=1;
42             else
43                 T[x]=y;
44         }
45     }
46     return 0;
47 }

 

 

 

 

http://codeforces.com/contest/698/problem/B

 

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 using namespace std;
 4 const int maxn = 1e5+10;
 5 int T[2*maxn], sum[2*maxn], a[2*maxn], flag = 0;
 6 int findn(int x){
 7     return x == T[x] ? x : T[x] = findn(T[x]);
 8 }
 9 int main(){
10     int n, num = 0, num2 = 0;
11     scanf("%d", &n);
12     for(int i = 1; i <= n; i++) T[i] = i;
13     for(int i = 1; i <= n; i++){
14         scanf("%d", &a[i]);
15         int xx = findn(i);
16         int yy = findn(a[i]);
17         if(xx == yy){
18             sum[num] = i, num++;
19             if(a[i] == i) flag = i;
20         } else{
21             T[xx] = yy;
22         }
23     }
24     if(!flag) {
25         for(int i = 1; i <= n; i++){
26             int xx = findn(i), yy = findn(a[i]);
27             if(xx == yy) flag = xx;
28         }
29     }
30     for(int i = 0; i < num; i++){
31         if(a[sum[i]] != flag){
32             num2++;
33             a[sum[i]] = flag;
34         }
35     }
36     printf("%d\n", num2);
37     for(int i = 1; i <= n; i++) printf("%d ",a[i]);
38     return 0;
39 }

 

 兽兽大神代码

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <vector>
 5 #include <algorithm>
 6 using namespace std;
 7 #define N 200200
 8 
 9 int bin[N];
10 int ans[N];
11 
12 int findfa(int x)
13 {
14     if(bin[x] == x) return x;
15     return bin[x] = findfa(bin[x]);
16 }
17 
18 int main()
19 {
20     int n;
21     cin>>n;
22     for(int i=0;i<N;i++) bin[i] = i;
23     int root = -1;
24     int anscnt = 0;
25     for(int i=1;i<=n;i++)
26     {
27         int tmp;
28         scanf("%d",&tmp);
29         if(tmp == i)
30         {
31             if( root != -1 )
32             {
33                 anscnt++;
34                 ans[ i ] = root;
35             }
36             else root = i,ans[i] = root;
37             continue;
38         }
39         int a = findfa(tmp);
40         int b = findfa(i);
41         if(a != b)
42         {
43             ans[i] = tmp;
44             bin[a] = b;
45         }
46         else anscnt++;
47     }
48     cout<<anscnt<<endl;
49     for(int i=1;i<=n;i++)
50     {
51         if(ans[i] != 0) printf("%d ",ans[i]);
52         else {
53             if(root == -1)
54             {
55                 root = i;
56                 printf("%d ",i);
57             }
58             else printf("%d ",root);//否则制定root
59         }
60     }
61     return 0;
62 }

 

 

只有不断学习才能进步!

 

以上是关于wenbao与并查集(关于成环与联通)的主要内容,如果未能解决你的问题,请参考以下文章

PAT-1021 Deepest Root (25 分) 并查集判断成环和联通+求树的深度

Restructuring Company和Almost Union-Find 并查集的区间合并与并查集的删除

大力飞砖之DFS与并查集(中-下)

HDU 1272 小希的迷宫(并查集,判断是否成环)

3.19 Tarjan算法与并查集解决二叉树节点间最近公共祖先的批量查询问题

货车运输