POJ 1182 食物链(并查集)

题目链接

经过宝哥的讲解,终于对这种问题有了进一步的理解。根据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 }

 

原文地址:https://www.cnblogs.com/naix-x/p/3140637.html