zoukankan      html  css  js  c++  java
  • 食物链(codevs 1074)

    题目描述 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 Description

    第一行是两个整数N和K,以一个空格分隔。   

    以下K行每行是三个正整数D,X,Y,两数之间用一个空格隔开,其中 D 表示说法的种类。   

    若D=1,则表示X和Y是同类。   

    若D=2,则表示X吃Y。

    输出描述 Output Description

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

    样例输入 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

    /*
      当前节点与父亲结点的关系:
        0 代表与父亲结点同类 
        1 代表被父亲结点吃
        2 代表吃父亲结点 
      我们开一个数组re[i],记录i号动物的种类情况。
      种类有三种,分别记为0,1,2,1吃0,2吃1,0吃2。
      对于每一个并查集,我们取根节点的类型为0.
    */
    #include<cstdio>
    #include<iostream>
    #define M 50010
    using namespace std;
    int re[M],fa[M],n,m;
    int find(int x)
    {
        if(x==fa[x])return x;
        int t=fa[x];
        fa[x]=find(fa[x]);
        re[x]=(re[x]+re[t])%3;//利用x的直接父亲t来更新x 
        return fa[x];
    } 
    /*建立关系时,先将两个子树的树根建立关系,之后两个数根与其子结点的关系在find函数中更新*/ 
    void build(int x,int y,int r)
    {
        int a=find(x),b=find(y);
        fa[a]=b;
        re[a]=(re[y]-re[x]+r+3)%3;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int ans=0;
        for(int i=1;i<=n;i++)fa[i]=i; 
        for(int i=1;i<=m;i++)
        {
            int f,x,y;
            scanf("%d%d%d",&f,&x,&y);
            if(x>n||y>n)
            {
                ans++;
                continue;
            }
            if(f==1)//同类 
            {
                if(find(x)!=find(y))build(x,y,0);
                else if(re[x]!=re[y])ans++;
            }
            else//x吃y,所以re[x]比re[y]大1 
            {
                if(find(x)!=find(y))build(x,y,1);
                else if(re[x]!=(re[y]+1)%3)ans++;
            }
        }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    BF算法和KMP算法
    Python课程笔记 (五)
    0268. Missing Number (E)
    0009. Palindrome Number (E)
    0008. String to Integer (atoi) (M)
    0213. House Robber II (M)
    0198. House Robber (E)
    0187. Repeated DNA Sequences (M)
    0007. Reverse Integer (E)
    0006. ZigZag Conversion (M)
  • 原文地址:https://www.cnblogs.com/harden/p/5622654.html
Copyright © 2011-2022 走看看