扩域并查集

 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 }

 

 

posted @ 2021-10-27 22:02  Hell0er  阅读(34)  评论(0编辑  收藏  举报