1. 程式人生 > 其它 >擴域並查集

擴域並查集

 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 }