poj1182

本文地址:https://www.cnblogs.com/maplefighting/p/9123814.html

题目名称:食物链

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

题意:中文题,自己看

思路:考察并查集。由于有三种动物,且不知种类,所以我们得分为三组i-A,i-B,i-C。i-X表示i属于种类X

若x和y同种,则合并x-A和y-A,x-B和y-B,x-C和y-C.

若x吃y,则合并x-A和y-B,x-B和y-C,x-C和y-A

代码如下:

 

 1 #include<cstdio>
 2 using namespace std;
 3 const int MAX_K = 100005;
 4 int n, k;
 5 int f[50000 * 3 + 5];
 6 void init(int n) {
 7     for(int i = 0; i < n; i++){
 8         f[i] = i;
 9     }
10 }
11 int found(int x) {
12     return f[x] == x ? x : f[x] = found(f[x]);
13 }
14 void unite(int x,int y) {
15     x = found(x), y = found(y);
16     if(x != y){
17         f[x] = y;
18     }
19     return ;
20 }
21 bool same(int x,int y) {
22     return found(x) == found(y);
23 }
24 int main(){
25     scanf("%d%d", &n, &k);
26     init(n * 3);
27     int sum = 0;
28     while(k--) {
29         int d, x, y;
30         scanf("%d%d%d", &d, &x, &y);
31         x--; y--;
32         if(x < 0 || y < 0 || x >= n || y >= n) {
33             sum++;
34             continue;
35         }
36         if(d == 1) {
37             //x和y为同类,判断x吃y或者y吃x为假
38             if(same(x, y + n) || same(y, x + n)) {
39                 sum++;
40             }
41             else {
42                 unite(x, y);
43                 unite(x + n, y + n);
44                 unite(x + 2 * n, y + 2 * n);
45             }
46         }
47         else {
48             //x吃y,判断x和y同类,或者y吃x为假
49             if(same(x, y) || same(y, x + n)){
50                 sum++;
51             }
52             else{
53                 unite(x, y+n);
54                 unite(x + n, y + 2 * n);
55                 unite(x + 2 * n, y);
56             }
57         }
58     }
59     printf("%d\n",sum);
60     return 0;
61 }
View Code

 

posted @ 2018-06-01 22:29  maplefighting  阅读(161)  评论(0编辑  收藏  举报