poj 1182 食物链

Description

动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。
现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是"1 X Y",表示X和Y是同类。
第二种说法是"2 X Y",表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。

Input

第一行是两个整数N和K,以一个空格分隔。
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。

Output

只有一个整数,表示假话的数目。

Sample Input

100 7
1 101 1 
2 1 2
2 2 3 
2 3 3 
1 1 3 
2 3 1 
1 5 5

Sample Output

3
该题是并查集的应用。
我们将数组分为3段,第一段表示A类,第二段表示B类,第三段表示C类
对每一个语句检查后加入到集合中

代码如下
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 int par[50002*3];
 9 int rank[50002*3];
10 
11 void init() {
12     memset(par, 0, sizeof(par));
13     memset(rank,0, sizeof(rank));
14 }
15 int find(int t) {
16     while(par[t] != 0) {
17         t = par[t];
18     }
19     return t;
20 }
21 
22 bool same(int x, int y) {
23     return find(x) == find(y);
24 }
25 
26 void unite(int x, int y) {
27     x = find(x);
28     y = find(y);
29     if(x == y) return;
30     if(rank[x] < rank[y]) {
31         par[x] = y;
32     }
33     else {
34         par[y] = x;
35         if(rank[x] == rank[y]) {
36             rank[x]++;
37         }
38     }
39 }
40 
41 int n, k;
42 int main(int argc, char const *argv[])
43 {
44     //freopen("input.txt","r",stdin);
45     scanf("%d %d",&n,&k);
46         int ans = 0;
47         init();
48         while(k--) {
49             int fa, x, y;
50             scanf("%d %d %d",&fa, &x, &y);
51             if(x > n || y > n || x <= 0 || y <= 0) {
52                 ans++;
53                 continue;
54                 
55             }
56             else if(fa == 1) {
57                 if(same(x,y+n) || same(x, y+2*n)) {
58                     //x eat y  or  y eat x
59                     ans++;
60                     continue;
61                 }
62                 else {
63                     unite(x,y);
64                     unite(x+n,y+n);
65                     unite(x+2*n,y+2*n);
66                 }
67             }
68             else if(fa == 2) {
69                 if(same(x,y) || same(x, y + 2*n)) {
70                     //x same y or y eat x
71                     ans++;
72                     continue;
73                 }
74                 else {
75                     unite(x,y+n);
76                     unite(x+n, y+2*n);
77                     unite(x+2*n, y);
78                 }
79             }
80         }
81         printf("%d\n",ans); 
82     return 0;
83 }

 

posted @ 2016-08-21 14:42  Jason杰  阅读(158)  评论(0编辑  收藏  举报