• NOI 2001:食物链


    题目描述
    
    动物王国中有三类动物 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 句话有的是真
    
    的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
    
    • 当前的话与前面的某些真的话冲突,就是假话
    
    • 当前的话中 X 或 Y 比 N 大,就是假话
    
    • 当前的话表示 X 吃 X,就是假话
    
    你的任务是根据给定的 N 和 K 句话,输出假话的总数。
    
    输入输出格式
    
    输入格式:
    从 eat.in 中输入数据
    
    第一行两个整数,N,K,表示有 N 个动物,K 句话。
    
    第二行开始每行一句话(按照题目要求,见样例)
    
    输出格式:
    输出到 eat.out 中
    
    一行,一个整数,表示假话的总数。
    
    输入输出样例
    
    输入样例#1100 7
    1 101 1
    2 1 2
    2 2 3
    2 3 3
    1 1 3
    2 3 1
    1 5 5
    
    输出样例#13
    题目

      芒果君:昨天刚学的并查集,还不太会写。然后做了一道什么王老菊太阳监狱,是把犯人分成两组,理解了好久,而这道题是分成三组:自己人(1~n),吃(n+1~2n),和被吃(2n+1~3n),看起来每一种动物都有独立的三组,但实际上我们用并查集把它们联系在一起了。在这道题里有两个阶段:判断和构建——判断是否存在矛盾,如果不矛盾就要添加这个新的并查集的边/节点。

    (顺便再把这行可爱的并查集的代码背一遍(好萌啊想捏一捏):return x==fa[x]?x:fa[x]=find(fa[x]);

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 int fa[300010],n,k,i,ans,a,b;
     6 int find(int x)
     7 {
     8     return x==fa[x]?x:fa[x]=find(fa[x]);
     9 }
    10 void link(int x,int y)
    11 {
    12     int k1=find(x),k2=find(y);
    13     if(k1!=k2) fa[k1]=k2;
    14 }
    15 int main()
    16 {
    17     int x;
    18     cin>>n>>k;
    19     for(i=1;i<=3*n;++i) fa[i]=i;
    20     for(i=1;i<=k;++i)
    21     {
    22         cin>>x>>a>>b;
    23         if(a>n||b>n||(a==b&&x==2)||a<1||b<1) ans++;
    24         else
    25         {
    26             if(x==1)
    27             {
    28                 if(find(a+n)==find(b)||find(a+n*2)==find(b)) ans++;
    29                 else
    30                 {
    31                     link(a,b);
    32                     link(a+n,b+n);
    33                     link(a+2*n,b+2*n);
    34                 }
    35             }
    36             else
    37             {
    38                 if(find(a)==find(b)||find(a+n*2)==find(b)) ans++;
    39                 else
    40                 {
    41                     link(a,b+2*n);
    42                     link(a+n,b);
    43                     link(a+2*n,b+n);
    44                 }
    45             }
    46         }
    47     }
    48     cout<<ans<<endl;
    49     return 0;
    50 }
  • 相关阅读:
    忘记mysql的登陆密码该怎么办?
    localhost和127.0.0.1的区别
    什么是DAPP
    System.NullReferenceException:未将对象引用设置到对象的实例,这是一个新鸟,中鸟,老鸟都避不开的错误
    VS2015中常用快捷键的修改推荐
    Win10系统开启IIS服务步骤
    ASP.NET学习路线图
    我眼中的技术地图
    WEBSTORM中html文件运行之后出现乱码的问题解决
    ExtJS新手学习中常见问题
  • 原文地址:https://www.cnblogs.com/12mango/p/7091131.html
Copyright © 2020-2023  润新知