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 }
  • 相关阅读:
    toj 2975 Encription
    poj 1797 Heavy Transportation
    toj 2971 Rotating Numbers
    zoj 2281 Way to Freedom
    toj 2483 Nasty Hacks
    toj 2972 MOVING DHAKA
    toj 2696 Collecting Beepers
    toj 2970 Hackle Number
    toj 2485 Card Tric
    js页面定位,相关几个属性
  • 原文地址:https://www.cnblogs.com/wangyiming/p/6357902.html
Copyright © 2011-2022 走看看