从去年学并查集的时候就想做 emmmm奈何那时脑子不够用
开三倍x 自身 x+2n 猎物 x+3n 天敌
然后按照那个关系来判断关系 猎物的猎物为天敌 天敌的天敌为猎物
要注意的是判断完要把三种关系都给合并了 我就合并了一种emmmmmmm
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<cmath> #include<stack> #include<algorithm> using namespace std; #define ll long long #define rg register const int N=200000+5,pw=11,inf=0x3f3f3f3f,P=19650827; int n,k,f[N],ans=0; template <class t>void rd(t &x) { x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } int find(int x){return f[x]==x?x:f[x]=find(f[x]);} void Union(int x,int y) {f[find(y)]=find(x);} int main() { //freopen("in.txt","r",stdin); //freopen("nocows.out","w",stdout); rd(n),rd(k); for(rg int i=1;i<=n*3;++i) f[i]=i; while(k--){ int op,x,y; rd(op),rd(x),rd(y); if(x>n||y>n) {++ans;continue;} if(op==1){ if(find(x+n)==find(y)||find(x+2*n)==find(y)) ++ans; //为猎物 为天敌 else Union(x,y),Union(x+n,y+n),Union(x+2*n,y+2*n); } else{ if(x==y) {++ans;continue;} if(find(x)==find(y)||find(x)==find(y+n)) ++ans; //为同类 为猎物 else Union(x,y+2*n),Union(x+n,y),Union(x+2*n,y+n); } } printf("%d",ans); return 0; }