并查集的变形使用
题目链接:https://cn.vjudge.net/contest/242366#problem/K
AC代码:
1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<iomanip> 5 #include<cmath> 6 #include<algorithm> 7 #include<stdio.h> 8 #include<map> 9 #include<queue> 10 #include<stack> 11 #include<vector> 12 using namespace std; 13 # define maxn 100000+10 14 # define ll long long 15 #define inf 0x3f3f3f3f 16 #define ll_inf 0x3f3f3f3f3f3f3f3f 17 int n,m; 18 int father[maxn],net[maxn]; 19 20 void init() 21 { 22 for(int i=1; i<=n; i++) 23 { 24 father[i]=i;//给每个点进行初始化 25 net[i]=0;//0 代表相同,1代表不同,最初的时候自己到自己肯定是相同的 26 } 27 } 28 int Find(int t) 29 { 30 int temp=father[t]; 31 if(t==father[t])return t;//如果是自己到自己,祖先当然是自己 32 father[t]=Find(father[t]);//寻找祖先节点 33 if(net[t]!=net[temp]) 34 { 35 net[t]=1; 36 } 37 else net[t]=0; 38 return father[t]; 39 } 40 void change(int t1,int t2,int t3,int t4) 41 { 42 father[t3]=t4;//首先进行归并 43 if(net[t1]==net[t2])//如果两个子节点的关系和父亲节点相同的时候,就把两个父亲节点中相对是子节点的bet变为1,否则变为0 44 { 45 net[t3]=1; 46 } 47 else net[t3]=0; 48 } 49 int main() 50 { 51 int T; 52 scanf("%d",&T); 53 while(T--) 54 { 55 scanf("%d %d",&n,&m); 56 init(); 57 while(m--) 58 { 59 char str; 60 int u,v; 61 getchar(); 62 scanf("%c %d %d",&str,&u,&v); 63 int t1=Find(u); 64 int t2=Find(v); 65 if(str=='A') 66 { 67 if(t1!=t2)//如果说这两个人的祖先都不一样,关系肯定确定不了 68 { 69 printf("Not sure yet.\n"); 70 continue; 71 } 72 if(net[u]==net[v])//在祖先相同的前提下,都和祖先的和关系相同,那么这俩人肯定是同一个帮派 73 { 74 printf("In the same gang.\n"); 75 } 76 else 77 { 78 printf("In different gangs.\n"); 79 } 80 } 81 else 82 { 83 if(t1!=t2) 84 { 85 change(u,v,t1,t2); 86 } 87 } 88 } 89 } 90 return 0; 91 } 92