zoukankan      html  css  js  c++  java
  • 食物链

    题目描述

            动物王国中有三类动物  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),输出假话的总数。

    输入

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

    输出

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

    样例输入

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

    样例输出

    3
    

    提示

    100 7
    1 101 1    假话 
    2 1 2      真话 
    2 2 3      真话 
    2 3 3      假话 
    1 1 3      假话 
    2 3 1      真话 
    1 5 5      真话 
     
    【胡乱分析】
    用1~n表示动物,n+1~2n表示吃某动物的动物,2n+1到3n表示被吃的动物;如:a+n表示吃a的,a+2n表示吃b的;所以一开始在存fa[]和size[]的时候也是1~3n。余下的看代码。这次主要的问题是语文,把三类动物和n个动物弄混了。
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 using namespace std;
     7 const int M = 200000;
     8 int fa[M],size[M];
     9 int find(int x)
    10 {
    11     if(fa[x] != x) return fa[x] = find(fa[x]);
    12     return fa[x];
    13 }
    14 void unionn(int x,int y)
    15 {
    16     x = find(x);
    17     y = find(y);
    18     if(x == y) return;//如果两个已经在同一个集合中了,就不用操作 
    19     else
    20     {
    21         if(size[x] > size[y])//小的往大的里合并 
    22         {
    23             size[x] += size[y];
    24             fa[y] = x; 
    25         }
    26         else
    27         {
    28             size[y] += size[x];
    29             fa[x] = y;
    30         }
    31     }
    32 }
    33 int main()
    34 {
    35     int n,k,d,a,b,ans = 0;
    36     scanf("%d%d",&n,&k);
    37     for(int i = 1;i <= 3 * n;i++)
    38     {
    39         fa[i] = i;
    40         size[i] = 1;
    41     }
    42     for(int i = 1;i <= k;i++)
    43     {
    44         scanf("%d%d%d",&d,&a,&b);
    45         if(a > n || b > n)//如果动物编号大于动物个数,则是假话 
    46         {
    47             ans++;
    48         }
    49         else
    50         {
    51             if(d == 1)
    52             {
    53                 if(find(a) == find(b + n) || find(a) == find(b + 2 * n)) ans++;//如果a和吃b的动物为一类,则a不可能跟b是同类;如果a和被b吃的是同类,他俩也不可能为同类 
    54                 else//如果这句话是真的 
    55                 {
    56                     unionn(a,b);//合并a,b为一类 
    57                     unionn(a + n,b + n);//吃a的动物也吃b 
    58                     unionn(a + 2 * n,b + 2 * n);//被a吃的动物也被b吃 
    59                 }
    60             }
    61             else
    62             {
    63                 if(find(a) == find(b) || find(a) == find(b + 2 * n)) ans++;//如果ab为一类或a与被b吃的是一类,则a不可能吃b 
    64                 else
    65                 {
    66                     unionn(a,b + n);//a和吃b 的是一类 
    67                     unionn(a + 2 * n,b);//被a吃的和b 是一类 
    68                     unionn(a + n,b + 2 * n);//由于一共有三类动物,所以吃a的和被b吃的是一类。 
    69                 }
    70             }
    71         }
    72     }
    73     printf("%d",ans);
    74     return 0;
    75 }
  • 相关阅读:
    hdu 4638 Group 线段树
    hdu 4635 Strongly connected 强连通分量
    hdu 4604 Deque
    hdu 1000 A + B Problem
    数组相关
    文本文件相关
    硬件电路中VCC,VDD,VEE,VSS有什么区别
    VIPM链接LabVIEW问题
    Touch实现轻扫
    touchesMoved 实现拖拽
  • 原文地址:https://www.cnblogs.com/peppa/p/9025247.html
Copyright © 2011-2022 走看看