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

    把一个点拆成三个,分别对应它的同类、它的猎物和它的天敌,这样的话(以下的相等都是并查集意义上的):

    如果令a,b同类,那么a的猎物不能是b的同类,a的天敌不能是b的同类

    如果令a吃b,那么a的同类不能是b的同类、a的天敌不能是b的同类。

    要令a,b同类,就使(a和b)的同类、猎物、天敌分别相等

    要令a吃b,就使a的猎物是b的同类,b的天敌是a的同类,a的天敌是b的猎物(题目中要求A吃B,B吃C,C吃A)

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define ll long long
     4 using namespace std;
     5 const int maxn=50050;
     6 
     7 inline ll rd(){
     8     ll x=0;char c=getchar();int neg=1;
     9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    11     return x*neg;
    12 }
    13 
    14 int N,K,fa[maxn*3];
    15 
    16 int getfa(int x){return x==fa[x]?x:fa[x]=getfa(fa[x]);}
    17 void add(int a,int b){
    18     fa[getfa(a)]=getfa(b);
    19 }
    20 
    21 int main(){
    22     //freopen("testdata.in","r",stdin);
    23     int i,j,k,ans=0;
    24     N=rd();K=rd();
    25     for(i=1;i<=N*3;i++) fa[i]=i;
    26     for(i=1;i<=K;i++){
    27         int a=rd(),b=rd(),c=rd();
    28         if(b>N||c>N) {++ans;continue;}
    29         if(a==1){
    30             if(getfa(b)==getfa(c+N)||getfa(b)==getfa(c+2*N)){++ans;continue;}
    31             add(b,c);add(b+N,c+N);add(b+2*N,c+2*N);
    32         }else{
    33             if(getfa(b)==getfa(c)||getfa(b+2*N)==getfa(c)){++ans;continue;}
    34             add(b+N,c);add(b,c+2*N);add(b+2*N,c+N);
    35         }
    36     }
    37     printf("%d
    ",ans);
    38     return 0;
    39 }
  • 相关阅读:
    背水一战 Windows 10 (90)
    背水一战 Windows 10 (89)
    背水一战 Windows 10 (88)
    背水一战 Windows 10 (87)
    背水一战 Windows 10 (86)
    背水一战 Windows 10 (85)
    背水一战 Windows 10 (84)
    背水一战 Windows 10 (83)
    背水一战 Windows 10 (82)
    背水一战 Windows 10 (81)
  • 原文地址:https://www.cnblogs.com/Ressed/p/9643721.html
Copyright © 2011-2022 走看看