并查集 食物链

 

https://www.luogu.org/problemnew/show/P2024

 

n(A)+n(B)+n(C)

 

两个点相连,代表两者是等效的(A<->B,若A成立,B也成立;若B成立,A也成立)。

一棵树上,如果有其中一个点成立,那么,树上的所有点也成立。

 

规定x+k*n,y+k*n代表x和y同类关系,x+k*n,y+(k+1)%3*n代表x吃y的关系。

 

1 x y

x,y same

如果x和y+n(或x和y+2*n)同属一棵树,那么代表x和y有吃(被吃)的关系,矛盾(这个跟A、B、C是没有任何相连,它只是代表着一种关系,如果x为A,那么y必为B(C),反映吃(被吃)的关系)

连(x,y)、(x+n,y+n)、(x+2*n,y+2*n)

 

2 x y

x eat y

如果x和y(或x和y+2*n)同属一棵树,那么代表x和y有同级(被吃)的关系,矛盾

连(x,y+n) (x+n,y+2*n) (x+2*n,y)

 

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <ctime>
 5 #include <cstring>
 6 #include <string>
 7 #include <map>
 8 #include <set>
 9 #include <list>
10 #include <queue>
11 #include <stack>
12 #include <vector>
13 #include <bitset>
14 #include <algorithm>
15 #include <iostream>
16 using namespace std;
17 #define ll long long
18 const int maxn=5e4+10;
19 
20 int fa[maxn*3];
21 
22 int getf(int d)
23 {
24     if (fa[d]==d)
25         return d;
26     fa[d]=getf(fa[d]);
27     return fa[d];
28 }
29 
30 void _union(int x,int y)
31 {
32     int xx=getf(x);
33     int yy=getf(y);
34     fa[xx]=yy;
35 }
36 
37 int main()
38 {
39     int n,t,mode,x,y,x1,y1,y2,lie=0,i;
40     scanf("%d%d",&n,&t);
41     for (i=1;i<=3*n;i++)
42         fa[i]=i;
43     ///x eat y k -> (k+n) mod (3*n)
44     ///judge:use any(both ok) ; handle:all
45     while (t--)
46     {
47         scanf("%d%d%d",&mode,&x,&y);
48         if (x>n || y>n)
49         {
50             lie++;
51             continue;
52         }
53         if (mode==1)
54         {
55             ///x,y same
56             x1=getf(x);
57             y1=getf(y+n);
58             y2=getf(y+n+n);
59             if (x1==y1 || x1==y2)
60                 lie++;
61             else
62             {
63                 _union(x,y);
64                 _union(x+n,y+n);
65                 _union(x+n+n,y+n+n);
66             }
67         }
68         else
69         {
70             ///x eat y
71             x1=getf(x);
72             y1=getf(y);
73             y2=getf(y+n+n);
74             if (x1==y1 || x1==y2)
75                 lie++;
76             else
77             {
78                 _union(x,y+n);
79                 _union(x+n,y+n+n);
80                 _union(x+n+n,y);
81             }
82         }
83     }
84     printf("%d",lie);
85     return 0;
86 }

 

posted @ 2018-11-17 00:26  congmingyige  阅读(209)  评论(0编辑  收藏  举报