扩域并查集
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 const int MAXN=50010; 6 int n,k; 7 int head[MAXN*3]; //一倍存同类,一倍存吃,一倍存被吃 8 9 int root(int x) 10 { 11 if (x==head[x]) return x; 12 else return head[x]=root(head[x]); 13 } 14 15 inline bool check1(int x,int y) //同类 16 { 17 if (root(x+n)==root(y) || root(x+2*n)==root(y)) return false; //x吃y || x被y吃 18 head[root(x)]=root(y); 19 head[root(x+n)]=root(y+n); 20 head[root(x+2*n)]=root(y+2*n); 21 return true; 22 } 23 inline bool check2(int x,int y) //x吃y 24 { 25 if (root(x)==root(y) || root(x+2*n)==root(y)) return false; //同类 || x被y吃 26 head[root(x)]=root(y+2*n); 27 head[root(x+n)]=root(y); 28 head[root(x+2*n)]=root(y+n); 29 return true; 30 } 31 32 int main() 33 { 34 scanf("%d%d",&n,&k); 35 for (int i=1;i<=3*n;i++) head[i]=i; 36 37 int ans=0; 38 for (int i=1;i<=k;i++) 39 { 40 int opt,x,y; 41 scanf("%d%d%d",&opt,&x,&y); 42 if (x>n || y>n) 43 { 44 ans++; 45 continue; 46 } 47 if (opt==1) //x与y是同类 48 { 49 if (!check1(x,y)) ans++; 50 } 51 else //x吃y 52 { 53 if (x==y) 54 { 55 ans++; 56 continue; 57 } 58 if (!check2(x,y)) ans++; 59 } 60 } 61 printf("%d\n",ans); 62 63 return 0; 64 }