poj 1182 食物链 (并查集)

题目连接:

  http://poj.org/problem?id=1182

题目大意:

  汉语题目,题目意思我就不废话了。

解题思路:

  遇到这一道题好像是在上一月下旬,当时看了不会又赶上快放假了,就一直放放放,就到现在。

根据集合的性质,可知一个集合里面任意两个元素肯定有对应关系,如果没有关系是不会被合并到一个集合里面的。

用father表示x,y是否在一个集合里面,用nexu表示x,y的关系,其中nexu[x] 表示x与x的父节点的关系,(如果x与其父节点同级,nexu[x]=0;如果x能被

其父节点吃掉,nexu[x] = 1;反正x能成吃掉其父节点,nexu[x] = 2;)这个题目主要解决的是路径压缩的时候父节点的改变,引起的nexu节点的改变。

http://blog.sina.com.cn/s/blog_807ca3aa0100tumm.html,神牛微博里讲的十分详细。ps:以前单实例当做多实例写就不会wa,但是这个题目就会。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 50005;
 8 int father[maxn], nexu[maxn], n;
 9 void init ();
10 int find (int x);
11 bool judge (int d, int x, int y);
12 int main ()
13 {
14     int k, s, x, y;
15     scanf ("%d %d", &n, &k);
16     init ();
17     int sum = 0;
18     while (k --)
19     {
20         scanf ("%d %d %d", &s, &x, &y);
21         if (judge (s-1, x, y))
22             sum ++;
23     }
24     printf ("%d\n", sum);
25     return 0;
26 }
27 
28 void init ()
29 {
30     memset (nexu, 0, sizeof(nexu));//初始化为0,因为自身与自身是同类
31     for (int i=0; i<maxn; i++)
32         father[i] = i;
33 }
34 
35 int find (int x)
36 {
37     if (x != father[x])
38     {
39         int tx = find (father[x]);//当父节点要改变,nexu[x]相对应也要改变
40         nexu[x] = (nexu[x] + nexu[father[x]])%3;
41         father[x] = tx;
42 
43     }
44     return father[x];
45 }
46 
47 bool judge (int d, int x, int y)
48 {
49     if (x>n || y>n)
50         return true;
51     if (d && x == y)
52         return true;
53     int px = find (x);
54     int py = find (y);
55     int num = (nexu[y] - nexu[x] + 3) % 3;
56     if (px == py )
57         if (num != d)
58             return true;
59         else
60             return false;
61     father[py] = px;//不在同一集合下的情况
62     nexu[py] = (nexu[x] + d - nexu[y] + 3) % 3;
63     return false;
64 }

 

posted @ 2015-02-05 13:15  罗茜  阅读(157)  评论(0编辑  收藏  举报