zoukankan      html  css  js  c++  java
  • 暑假集训(2)第三弹 ----- 食物链(poj1182)

    C - 食物链

    Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld & %llu

    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


    问题分析:也是并查集,不过增加了三种属性,吃,同类,被吃,据其他人的解题报告,得知假设同类为0,吃为1,被吃为2,
    其中有一个关系就是(父结点与爷爷结点的关系 + 儿子与父结点的关系)%3 = 儿子对爷爷的关系,通过它可以得到答案。
     1 #include "cstdio"
     2 
     3 int a[50001];
     4 int re[50001];
     5 int number;
     6 void abegin(int n)
     7 {
     8     for (int i=1;i<=n;i++)
     9        {
    10             a[i] = i;
    11             re[i] = 0;
    12        }
    13 }
    14 int findroot(int x)
    15 {
    16     if(x != a[x])
    17      {
    18         int temp = a[x];
    19         a[x] = findroot(temp);
    20         re[x] = (re[x] + re[temp]) % 3;
    21      }
    22    return a[x];
    23 }
    24 void un(int b,int c,int d)
    25 {
    26    int x,y;
    27    x = findroot(c);
    28    y = findroot(d);
    29    if (x == y)
    30    {
    31         if (b == 1 &&  re[c] != re[d])
    32                  number++;
    33         if (b == 2 && re[c] != (re[d] + 2) % 3)
    34                  number++;
    35    }
    36    else
    37    {
    38         a[y] = x;
    39         re[y] = (re[c] + b + 2 - re[d]) % 3;
    40    }
    41 }
    42 int main()
    43 {
    44     int n,k;
    45     int c,d,b;
    46     scanf("%d%d",&n,&k);
    47     number=0;
    48     abegin(n);
    49     while (k--)
    50     {
    51         scanf ("%d%d%d",&b,&c,&d);
    52         if (c>n || d>n ||(b==2 && c==d))
    53         {
    54             number++;
    55             continue;
    56         }
    57         un (b,c,d);
    58     }
    59     printf ("%d
    ",number);
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    Node Introduce
    鼠标拖动物体
    给模型自动赋予贴图代码
    JS读取XML
    动态控件01
    背包代码
    输出文本信息在U3D读取切换SHADER的SCRIPT测试
    材质球一闪一闪
    适配器模式1
    简单工厂,工厂方法的区别总结
  • 原文地址:https://www.cnblogs.com/huas-zlw/p/5696991.html
Copyright © 2011-2022 走看看