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\n",ans);

78     return 0;

79 }

 

 

你可能感兴趣的:(poj)