经过宝哥的讲解,终于对这种问题有了进一步的理解。根据flag[x]和flag[y]求flag[tx]是最关键的了。
0吃1,1吃2,2吃0.
假设flag[tx] = X;
那么X + flag[x] = flag[y] + 2 (当x吃y的时候)
1 #include <cstring> 2 #include <cstdio> 3 #include <string> 4 #include <iostream> 5 #include <algorithm> 6 #include <vector> 7 using namespace std; 8 int o[50001]; 9 int flag[50001]; 10 int ans; 11 int find(int x) 12 { 13 if (x == o[x]) return x; 14 int t = find(o[x]); 15 flag[x] = (flag[o[x]] + flag[x]) % 3; 16 return o[x] = t; 17 } 18 void judge1(int x,int y) 19 { 20 int tx,ty; 21 tx = find(x); 22 ty = find(y); 23 if(tx != ty) 24 { 25 o[tx] = ty; 26 flag[tx] = (flag[y] - flag[x] + 3)%3; 27 } 28 else if(tx == ty) 29 { 30 if(flag[x] != flag[y]) 31 ans ++; 32 } 33 } 34 void judge2(int x,int y)//x吃y 35 { 36 int tx,ty; 37 tx = find(x); 38 ty = find(y); 39 if(tx != ty) 40 { 41 o[tx] = ty; 42 flag[tx] = (flag[y] - flag[x] + 5)%3; 43 } 44 else if(tx == ty) 45 { 46 if((flag[x]-flag[y]+3)%3 != 2) 47 ans ++; 48 } 49 } 50 int main() 51 { 52 int n,m,num,sv,ev,i; 53 scanf("%d%d",&n,&m); 54 ans = 0; 55 for(i = 1; i <= n; i ++) 56 { 57 o[i] = i; 58 flag[i] = 0; 59 } 60 for(i = 0; i < m; i ++) 61 { 62 scanf("%d%d%d",&num,&sv,&ev); 63 if(sv > n||ev > n) 64 { 65 ans ++; 66 continue; 67 } 68 if(num == 1) 69 { 70 judge1(sv,ev); 71 } 72 else 73 { 74 judge2(sv,ev); 75 } 76 } 77 printf("%d ",ans); 78 return 0; 79 }