扩展域并查集解决了有多种相互关系的问题。这题如果单纯的去判断是不是同类就是用普通的并查集就可以了。但由于有想吃的关系,所以得使用扩展域并查集,有三种动物,将并查集的数组扩大三倍。对于某x,y两个动物是同类的情况这两个动物可能是A,B,C任意一种。那么将x,y合并。x+n,y+n合并。y+2*n,x+2*n合并。来代表他们是同一种动物。如果x吃y的话,那么假设x为A,y+n是B。所以将x和y+n合并表示x吃y的关系。同样如果x是B或C也要进行合并。
这样我们要进行判断的时候,一个是判断数据是否合理,
如果D==1的话判断x,y有没有之前已经记录的吃的关系。
如果D==2的话判断x,y有没有记录过得同类的关系以及有没有y吃x的关系。
#include <bits/stdc++.h> // #define int long long using namespace std; const int maxn = 200000; int a[maxn]; int find(int x) { if (a[x]==x) { return x; } else { return a[x] = find(a[x]); } } void Merge(int x, int y) { int rootx = find(x); int rooty = find(y); a[rootx] = rooty; } signed main() { // for (int i=0;i<maxn;i++) { a[i] = i; } int n, k; int ans =0 ; int d, x, y; cin>>n>>k; for (int i=0;i<k;i++) { cin>>d>>x>>y; if (d==1) { if (x>n||y>n||find(x+n)==find(y)||find(y+n)==find(x)) { ans++; } else { Merge(x, y); Merge(x+n, y+n); Merge(x+2*n, y+2*n); } } else { if (x>n||y>n||x==y||find(x)==find(y)||find(y)==find(x+n)) { ans++; } else { Merge(x, y+n); Merge(x+n, y+2*n); Merge(x+2*n, y); } } } cout<<ans<<endl; return 0; }