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

    题意:

    三类动物A、B、C,A吃B,B吃C,C吃A。
    给出K句话来描述N个动物(各属于A、B、C三类之一)之间的关系,格式及意义如下:
    1 X Y:表示X与Y是同类;
    2 X Y:表示X吃Y。
    K句话中有真话有假话,当一句话满足下列三条之一时,这句话就是假话,否则就是真话。1)当前的话与前面的某些真的话冲突,就是假话;2)当前的话中X或Y比N大,就是假话;3)当前的话表示X吃X,就是假话。
    求假话的总数。

    输入:
    第一行是两个整数N和K,以一个空格分隔。以下K行每行是三个正整数D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。若D=1,则表示X和Y是同类。若D=2,则表示X吃Y。
    输出:
    只有一个整数,表示假话的数目。
    约束条件:
    1 <= N <= 50000,0 <= K <= 100000。

    思路:

    并查集中的元素并不是动物,而是每只动物属于某种类别的信息。

    具体来说,对于每只动物i创建i-A,i-B,i-C,并用这3*N个元素建立并查集。i-x表示“i属于种类x”。并查集里的每一个组内表示所有元素代表的情况同时发生或不发生。

    对于x和y属于同一种类这种信息,合并x-A和y-A,x-B和y-B,x-C和y-C;

    对于x吃y这种信息,合并x-A和y-B,x-B和y-C,x-C和y-A。

    合并之前检查是否矛盾并计数即可。

    实现:

     1 #include <iostream>
     2 #include <cstdio>
     3 #define MAXN 50000
     4 using namespace std;
     5 int a[MAXN + 10];
     6 int par[3 * MAXN + 10];
     7 int ran[3 * MAXN + 10];
     8 void init(int n)
     9 {
    10     for (int i = 0; i <= n; i++)
    11     {
    12         par[i] = i;
    13         ran[i] = 0;
    14     }
    15 }
    16 int find(int x)
    17 {
    18     if (x == par[x])
    19         return x;
    20     return par[x] = find(par[x]);
    21 }
    22 void unite(int x, int y)
    23 {
    24     x = find(x);
    25     y = find(y);
    26     if (x == y)
    27     {
    28         return;
    29     }
    30     if (ran[x] < ran[y])
    31     {
    32         par[x] = y;
    33     }
    34     else
    35     {
    36         par[y] = x;
    37         if (ran[x] == ran[y])
    38         {
    39             ran[x]++;
    40         }
    41     }
    42 }
    43 bool same(int x, int y)
    44 {
    45     return find(x) == find(y);
    46 }
    47 int main()
    48 {
    49     int n, k, t, x, y;
    50     cin >> n >> k;
    51     int cnt = 0;
    52     init(3 * n);
    53     for (int i = 0; i < k; i++)
    54     {
    55         scanf("%d %d %d", &t, &x, &y);
    56         if (x <= 0 || x > n || y <= 0 || y > n)
    57         {
    58             cnt++;
    59             continue;
    60         }
    61         x--;
    62         y--;
    63         if (t == 1)
    64         {
    65             if (same(x + n, y + 2 * n) || same(x + n, y))
    66             {
    67                 cnt++;
    68             }
    69             else
    70             {
    71                 unite(x, y);
    72                 unite(x + n, y + n);
    73                 unite(x + 2 * n, y + 2 * n);
    74             }
    75         }
    76         else
    77         {
    78             if (same(x + n, y) || same(x + 2 * n, y + 2 * n))
    79             {
    80                 cnt++;
    81             }
    82             else
    83             {
    84                 unite(x, y + n);
    85                 unite(x + n, y + 2 * n);
    86                 unite(x + 2 * n, y);
    87             }
    88         }
    89     }
    90     cout << cnt << endl;
    91     return 0;
    92 }
  • 相关阅读:
    Python基础
    XML文件的基础使用
    正则表达式的基本使用
    hafs的java_api(转载)
    HDFS常用的Shell命令(转载)
    安装hadoop2.4.1
    配置JDK环境变量
    准备Linux环境
    Winform窗体屏蔽Alt+F4强制关闭
    leetcode 0214
  • 原文地址:https://www.cnblogs.com/wangyiming/p/6357902.html
Copyright © 2011-2022 走看看