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 并查集的区间合并与并查集的删除