题目连接:
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 ", 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 }