思路:写了这题https://www.cnblogs.com/2462478392Lee/p/11343747.html就很容易理解,并想出思路了。开一个3*n的数组,将x与y的同类,捕食者,和被捕食做扩展域,
然后利用其中的关系做并查集,每一种情况均有三种。当x与y为同类时,同类同类,x的捕食者与y的捕食者,x的被捕食与y的被捕食。当x捕食y时,x与y的捕食者,x的被捕食
与y,x的捕食者与y的被捕食。建立并查集后查看多少种不符合当前并查集情况即可求出答案。
#include<cstring> #include<algorithm> #include<vector> #include<map> #include<queue> #include<cstdio> #include<cmath> #define ll long long using namespace std; int fa[2000000]; int get(int k) { return fa[k]==k?k:fa[k]=get(fa[k]); } void merge(int x,int y) { fa[get(x)]=get(y); } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=3*n;i++) { fa[i]=i; } int ans=0; for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(b>n||c>n) ans++; else if(a==1) { if(get(b)==get(c+n)||get(b)==get(c+n+n)) ans++; else { merge(b,c); merge(b+n,c+n); merge(b+n+n,c+n+n); } } else { if(b==c||get(b)==get(c)||get(c+n)==get(b)) ans++; else { merge(b+n,c); merge(b,c+n+n); merge(b+n+n,c+n); } } } printf("%d ",ans); }