zoukankan      html  css  js  c++  java
  • 并查集 食物链

    https://www.luogu.org/problemnew/show/P2024

    n(A)+n(B)+n(C)

    两个点相连,代表两者是等效的(A<->B,若A成立,B也成立;若B成立,A也成立)。

    一棵树上,如果有其中一个点成立,那么,树上的所有点也成立。

    规定x+k*n,y+k*n代表x和y同类关系,x+k*n,y+(k+1)%3*n代表x吃y的关系。

    1 x y

    x,y same

    如果x和y+n(或x和y+2*n)同属一棵树,那么代表x和y有吃(被吃)的关系,矛盾(这个跟A、B、C是没有任何相连,它只是代表着一种关系,如果x为A,那么y必为B(C),反映吃(被吃)的关系)

    连(x,y)、(x+n,y+n)、(x+2*n,y+2*n)

    2 x y

    x eat y

    如果x和y(或x和y+2*n)同属一棵树,那么代表x和y有同级(被吃)的关系,矛盾

    连(x,y+n) (x+n,y+2*n) (x+2*n,y)

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <ctime>
     5 #include <cstring>
     6 #include <string>
     7 #include <map>
     8 #include <set>
     9 #include <list>
    10 #include <queue>
    11 #include <stack>
    12 #include <vector>
    13 #include <bitset>
    14 #include <algorithm>
    15 #include <iostream>
    16 using namespace std;
    17 #define ll long long
    18 const int maxn=5e4+10;
    19 
    20 int fa[maxn*3];
    21 
    22 int getf(int d)
    23 {
    24     if (fa[d]==d)
    25         return d;
    26     fa[d]=getf(fa[d]);
    27     return fa[d];
    28 }
    29 
    30 void _union(int x,int y)
    31 {
    32     int xx=getf(x);
    33     int yy=getf(y);
    34     fa[xx]=yy;
    35 }
    36 
    37 int main()
    38 {
    39     int n,t,mode,x,y,x1,y1,y2,lie=0,i;
    40     scanf("%d%d",&n,&t);
    41     for (i=1;i<=3*n;i++)
    42         fa[i]=i;
    43     ///x eat y k -> (k+n) mod (3*n)
    44     ///judge:use any(both ok) ; handle:all
    45     while (t--)
    46     {
    47         scanf("%d%d%d",&mode,&x,&y);
    48         if (x>n || y>n)
    49         {
    50             lie++;
    51             continue;
    52         }
    53         if (mode==1)
    54         {
    55             ///x,y same
    56             x1=getf(x);
    57             y1=getf(y+n);
    58             y2=getf(y+n+n);
    59             if (x1==y1 || x1==y2)
    60                 lie++;
    61             else
    62             {
    63                 _union(x,y);
    64                 _union(x+n,y+n);
    65                 _union(x+n+n,y+n+n);
    66             }
    67         }
    68         else
    69         {
    70             ///x eat y
    71             x1=getf(x);
    72             y1=getf(y);
    73             y2=getf(y+n+n);
    74             if (x1==y1 || x1==y2)
    75                 lie++;
    76             else
    77             {
    78                 _union(x,y+n);
    79                 _union(x+n,y+n+n);
    80                 _union(x+n+n,y);
    81             }
    82         }
    83     }
    84     printf("%d",lie);
    85     return 0;
    86 }
  • 相关阅读:
    [题解](组合数/二位前缀和)luogu_P2822组合数问题
    [题解](tarjan割点/点双)luogu_P3225_矿场搭建
    [题解](树形dp/换根)小x游世界树
    [題解](DP)CF713C_Sonya and Problem Wihtout a Legend
    [題解]hdu_6412公共子序列
    [題解](最小生成樹)luogu_P2916安慰奶牛
    [题解](堆)luogu_P1631序列合并
    [题解](最短路)luogu_P5122 Fine Dining
    [题解](次短路)luogu_P2865路障(未)
    [题解](最短路(树))luogu_P5201_short cut
  • 原文地址:https://www.cnblogs.com/cmyg/p/9972563.html
Copyright © 2011-2022 走看看