zoukankan      html  css  js  c++  java
  • 洛谷P2024 食物链

     挺神奇

    题目描述

    动物王国中有三类动物 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 中

    一行,一个整数,表示假话的总数。

    输入输出样例

    输入样例#1:
    100 7
    1 101 1
    2 1 2
    2 2 3
    2 3 3
    1 1 3
    2 3 1
    1 5 5
    
    输出样例#1:
    3
    

    说明

    1 ≤ N ≤ 5 ∗ 10^4

    1 ≤ K ≤ 10^5

    并查集

    学习之前做过的关押罪犯(NOIP2010,洛谷P1525)的“镜像”思想,开了三个并查集。对于一个结点x:  x集表示同类,x+n集表示x吃的动物集,x+2n表示吃x的动物集

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 using namespace std;
     8 const int mxn=50010;
     9 int n;
    10 int f[mxn*3];
    11 //f[x]表示x的同类集  f[x+n]表示x吃的动物集 f[x+2n]表示吃x的动物集 
    12 int k;
    13 int ans=0;
    14 int find(int x){
    15     if(f[x]==x)return x;
    16     else return f[x]=find(f[x]);
    17 }
    18 void hb(int x,int y){
    19     int fx=find(x);
    20     int fy=find(y);
    21     if(fx!=fy) f[fx]=fy;
    22     return;
    23 }
    24 bool pd(int a,int x,int y){
    25     if(x>n || y>n ||x<1 || y<1)return false;//x或y大于n是假话 
    26     if(a==1){//同类 
    27 
    28         //int fx1=find(x+n);//吃x的集 
    29         if(find(x+n)==find(y) || find(x+2*n)==find(y))return false;
    30         hb(x,y);
    31         hb(x+n,y+n);
    32         hb(x+2*n,y+2*n);
    33         //如果是真话,合并为同类 
    34     }
    35     if(a==2){//非同类 
    36         if(x==y)return false;//自己吃自己是假话 
    37         if(find(x)==find(y) || find(x+2*n)==find(y))return false;
    38         hb(y,x+n);
    39         hb(y+2*n,x);
    40         hb(x+2*n,y+n);
    41     }
    42     return true;
    43 }
    44 int main(){
    45     int c;
    46     int x,y;
    47     scanf("%d%d",&n,&k);
    48     int i,j;
    49     int len=n*3;
    50     for(i=1;i<=len;i++)f[i]=i;//初始化 
    51     for(i=1;i<=k;i++){
    52         scanf("%d%d%d",&c,&x,&y);
    53         if(!pd(c,x,y))ans++;
    54     }
    55     printf("%d
    ",ans);
    56     return 0;
    57 }
  • 相关阅读:
    HDU4366 Successor 线段树+预处理
    POJ2823 Sliding Window 单调队列
    HDU寻找最大值 递推求连续区间
    UVA846 Steps 二分查找
    HDU3415 Max Sum of MaxKsubsequence 单调队列
    HDU时间挑战 树状数组
    UVA10168 Summation of Four Primes 哥德巴赫猜想
    UESTC我要长高 DP优化
    HDUChess 递推
    HDU4362 Dragon Ball DP+优化
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5557977.html
Copyright © 2011-2022 走看看