食物链
洛谷P2024 食物链
经典并查集,开3倍并查集,x,x+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; }