食物链 POJ

来源:互联网 发布:古墓丽影10优化补丁 编辑:程序博客网 时间:2024/06/07 22:04

题目链接:点我


动物王国中有三类动物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 71 101 1 2 1 22 2 3 2 3 3 1 1 3 2 3 1 1 5 5

Sample Output

3

题意:

中文题目,题意很清晰,

思路:

带权并查集或者分组并查集都可以做,这里我用的分组并查集,

我们开三个并查集来维护三类动物之间的关系,每次加入之前先判断是否冲突,然后将他们加入并查集,并且加入的时候我们要加入三次,具体请看代码注释,

代码:

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;const int maxn = 50000 * 3 + 10;int f[maxn];int getf(int x){    if(f[x] == x) return x;    return f[x] = getf(f[x]);}void Merge(int x, int y){    int t1 = getf(x);    int t2 = getf(y);    if(t1 != t2){        f[t2] = t1;    }}int main(){    int n, k;   scanf("%d %d", &n, &k);        for(int i = 1; i <= n+n+n; ++i)            f[i] = i;        int ans = 0;        while(k--){            int d, x, y;            scanf("%d %d %d", &d, &x, &y);            if(x > n || y > n || (d ==2 && x == y)){                ++ans;                continue;            }            if(d == 1){                if(getf(x)==getf(y+n)||getf(x)==getf(y+n+n))                    ++ans;//判断他们是否构成吃与被吃的关系            else {                Merge(x,y);//他们是同类,所以加入一组并查集中,                Merge(x + n, y + n);                Merge(x + n + n, y + n + n);                }            }else {                if(getf(x) == getf(y)||getf(x)==getf(y+n+n))                    ++ans;//判断是否 x 与 y构成同类或者 反吃的情况               else {                    Merge(x,y+n);//A 吃 B                    Merge(x+n,y+n+n);//B 吃 C                    Merge(x+n+n,y);//C 吃 A                }            }        }        printf("%d\n",ans);    return 0;}
原创粉丝点击