• P2024 NOI2001 种类冰茶鸡


     展开

    题目描述

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

    思路

      换了和之前不同的种类并查集来解决此类问题,用n 2n 3n 三个集合来表明不同的关系;

      n为平等集合, 2n为生产者集合, 3n为捕食者集合.

      根据题意给出的不同关系加入不同的并查集.

    CODE

     1 #include <bits/stdc++.h>
     2 #define dbg(x) cout << #x << "=" << x << endl
     3 #define eps 1e-8
     4 #define pi acos(-1.0)
     5 
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 template<class T>inline void read(T &res)
    10 {
    11     char c;T flag=1;
    12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    14 }
    15 
    16 namespace _buff {
    17     const size_t BUFF = 1 << 19;
    18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
    19     char getc() {
    20         if (ib == ie) {
    21             ib = ibuf;
    22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
    23         }
    24         return ib == ie ? -1 : *ib++;
    25     }
    26 }
    27 
    28 int qread() {
    29     using namespace _buff;
    30     int ret = 0;
    31     bool pos = true;
    32     char c = getc();
    33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
    34         assert(~c);
    35     }
    36     if (c == '-') {
    37         pos = false;
    38         c = getc();
    39     }
    40     for (; c >= '0' && c <= '9'; c = getc()) {
    41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
    42     }
    43     return pos ? ret : -ret;
    44 }
    45 
    46 const int maxn = 2e5 + 7;
    47 
    48 int fa[maxn];
    49 int n,k;
    50 
    51 int fid(int x) {
    52     return x == fa[x] ? x : fid(fa[x]);
    53 }
    54 
    55 void init() {
    56     for ( int i = 1; i <= 3 * n; ++i ) {
    57         fa[i] = i;
    58     }
    59 }
    60 
    61 int main()
    62 {
    63     scanf("%d %d",&n, &k);
    64     init();
    65     int ans = 0;
    66     for ( int i = 1; i <= k; ++i ) {
    67         int x, y, opt;
    68         scanf("%d %d %d",&opt, &x, &y);
    69         if(x > n || y > n) {
    70             ans++;
    71             continue;
    72         }
    73         if(opt == 1) {
    74             if(fid(x) == fid(y + n) || fid(x + n) == fid(y)) {
    75                 ans++;
    76                 continue;
    77             }
    78             fa[fid(x)] = fid(y);
    79             fa[fid(x + n)] = fid(y + n);
    80             fa[fid(x + 2 * n)] = fid(y + 2 * n);
    81         }
    82         else if(opt == 2) {
    83             if(fid(x) == fid(y) || fid(x) == fid(y + n)) {
    84                 ans++;
    85                 continue;
    86             }
    87             fa[fid(x + n)] = fid(y);
    88             fa[fid(x)] = fid(y + 2 * n);
    89             fa[fid(x + 2 * n)] = fid(y + n);//捕食者集合连生产者集合
    90         }
    91     }
    92     cout << ans << endl;
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    ORM轻量级框架---ActiveAndroid
    面向对象系列一(继承)
    【Android自己定义View实战】之自己定义超简单SearchView搜索框
    POJ 2367:Genealogical tree(拓扑排序)
    计算客 商品推荐走马灯(简单)(求区间全部连续的回文串价值)
    供电电路切换与锂电池充电电路设计
    锂电池充电电路及电源自动切换电路的设计
    电池和Adapter切换电路改进实验(转)
    串口通信中ReadFile和WriteFile的超时详解!
    CRC算法与实现
  • 原文地址:https://www.cnblogs.com/orangeko/p/12374313.html
Copyright © 2020-2023  润新知