• 食物链 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


    解题思路:这道题要我们得出假话的数目,如果这就话和之前的话冲突就是假话。我开始没有什么思路,看了看样例,随手画出了图,感觉像是图论的东西,但其实再仔细想想,其实这是一种状态的划分!!!比如说a和b是同类关系,那就把a和b划分到一个集合中,之后再说a和b是捕食关系一定是假话了。但是这道题的问题在于某一个动物在食物链中的角色不是一定的,一个物种可能作为捕食者也可能是被捕食者,还有可能给出同类之间的关系,那该怎么办呢?将所扮演的三种状态全都表示出来。列如,对于物种x,x代表A类,x+n代表B类,x+2n代表c类,其中A吃B,B吃C,C吃A。

    对于两个动物如果是同类关系,那么一定不存在捕食和被捕食关系;如果存在捕食关系,那么一定不存在被捕食和同类关系。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define MAX 50010*3
     5 using namespace std;
     6 int pre[MAX];
     7 int Find(int x)
     8 {
     9     int a;
    10     a=x;
    11     while(pre[a]!=a)
    12     {
    13         a=pre[a];
    14     }
    15     return a;
    16 }
    17 void Union(int root1,int root2)
    18 {
    19     int x,y;
    20     x=Find(root1);
    21     y=Find(root2);
    22     if(x!=y)
    23     {
    24         pre[x]=y;
    25     }
    26 }
    27 int Same(int x,int y)///判断两个物种是否有关系
    28 {
    29     return Find(x)==Find(y);
    30 }
    31 int main()
    32 {
    33     int n,m,i,counts;
    34     int a,b,q;
    35     scanf("%d%d",&n,&m);
    36     counts=0;
    37     for(i=1;i<=n*3;i++)///开三倍的数组
    38     {
    39         pre[i]=i;
    40     }
    41     for(i=1;i<=m;i++)
    42     {
    43         scanf("%d%d%d",&q,&a,&b);
    44         if(a<1||a>n||b<1||b>n)///输入的数不合法为假话
    45         {
    46             counts++;
    47             continue;
    48         }
    49         if(q==1)
    50         {
    51             if(Same(a,b+n)||Same(a,b+2*n))///存在捕食关系或者被捕食关系
    52             {
    53                 counts++;
    54             }
    55             else///建立同类关系
    56             {
    57                 Union(a,b);
    58                 Union(a+n,b+n);
    59                 Union(a+2*n,b+2*n);
    60             }
    61         }
    62         else if(q==2)
    63         {
    64             if(Same(a,b)||Same(a,b+2*n))///存在同类或者被捕食关系
    65             {
    66                 counts++;
    67             }
    68             else///建立所有的捕食关系
    69             {
    70                 Union(a,b+n);
    71                 Union(a+n,b+2*n);
    72                 Union(a+2*n,b);
    73             }
    74         }
    75     }
    76     printf("%d
    ",counts);
    77     return 0;
    78 }
  • 相关阅读:
    公安的方案特点。
    12345
    js发送邮件 不会调用客户端。
    jsonp 跨域 jsonp 发音
    RESTful restful api Representational State Transfer
    Autofac 组件、服务、自动装配 《第二篇》
    Fiddler关闭自动更新
    武大樱花抢票软件使用说明
    Visual Studio实用小技巧
    C#6.0语法特性
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/9726554.html
Copyright © 2020-2023  润新知