食物链

洛谷P2024 食物链

经典并查集,开3倍并查集,xx+n表示x吃,x+2*n表示吃x,冲突就ans+1,否则不断更新,主要更新捕食关系时要满足环形。

#include<bits/stdc++.h>
using namespace std;

int dad[160010];
int n,k;

void Cin(int &x)
{
    char c=getchar();x=0;
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
}

long long ans;

int getfather(int x)
{
    if(dad[x]==x) return x;
    dad[x]=getfather(dad[x]);
    return dad[x];
}

int main()
{

    Cin(n),Cin(k);
    for(int i=1;i<=3*n;i++) dad[i]=i;
    
    int t,x,y;
    while(k--)
    {
        Cin(t),Cin(x),Cin(y);
        if(x>n||y>n||(t==2&&x==y))
        {
            ans++;
            continue;
        }
        
        
        if(t==1)
        {
            if(getfather(x+n)==getfather(y)||getfather(x+2*n)==getfather(y)||getfather(x)==getfather(y+n)||getfather(x)==getfather(y+2*n))
            {
                ans++;
                continue;
            }
            if(getfather(x)!=getfather(y))
            {
                dad[getfather(x)]=getfather(y);
                dad[getfather(n+x)]=getfather(n+y);
                dad[getfather(2*n+x)]=getfather(2*n+y);
            }
        }
        
        
        if(t==2)
        {
            if(getfather(x)==getfather(y)||getfather(x+2*n)==getfather(y)||getfather(x)==getfather(y+n))
            {
            ans++;
            continue;
            }
            dad[getfather(x+n)]=getfather(y);
            dad[getfather(y+2*n)]=getfather(x);
            dad[getfather(y+n)]=getfather(2*n+x);
        }
        
        
    }
    cout<<ans;
    return 0;
}
原文地址:https://www.cnblogs.com/war1111/p/7364019.html