扩展域并查集解决了有多种相互关系的问题。这题如果单纯的去判断是不是同类就是用普通的并查集就可以了。但由于有想吃的关系,所以得使用扩展域并查集,有三种动物,将并查集的数组扩大三倍。对于某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;
}

京公网安备 11010502036488号