poj1703 Find them, Catch them (带权并查集)
1 #include<cstdio> 2 const int N=1e5+1; 3 int f[N]; 4 int r[N];//表示与父节点的关系,0同类,1不同类 5 int n; 6 void init(){ 7 for(int i=1;i<=n;++i){ 8 f[i]=i; r[i]=0; 9 } 10 } 11 int fin(int x){ 12 int t; 13 if(x==f[x])return x; 14 t=f[x];//记录父节点 15 f[x]=fin(f[x]); 16 r[x]^=r[t];//类别偏移,或r[x]=(r[x]+r[t])%2 17 return f[x]; 18 } 19 void uni(int x,int y){ 20 int fx=fin(x); 21 int fy=fin(y); 22 f[fx]=fy; 23 r[fx]=~(r[x]^r[y]);//类别偏移,或r[fx]=(-r[x]+1+r[y]+2)%2 24 // 关系:fx与fy= fx与x+ x与y + y与fy 25 } 26 int main(){ 27 int t,m,a,b; 28 char s[3]; 29 scanf("%d",&t); 30 while(t--){ 31 scanf("%d%d",&n,&m); 32 init(); 33 while(m--){ 34 scanf("%s%d%d",s,&a,&b); 35 if(s[0]=='D') uni(a,b); 36 else{ 37 if(fin(a)!=fin(b)){ 38 if(n==2) printf("In different gangs.\n"); 39 else printf("Not sure yet.\n"); 40 } 41 else{ 42 if(r[a]==r[b]) 43 printf("In the same gang.\n"); 44 else printf("In different gangs.\n"); 45 } 46 } 47 } 48 } 49 return 0; 50 }