https://blog.csdn.net/qq_42505741/article/details/81104742
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
#define IO ios::sync_with_stdio(false);cin.tie(0);
#define endl '\n'
const int maxn=5e4+5;
int n,k;
int rel[maxn],pre[maxn];//rel数组表示关系 0同类 1x吃y 2y吃x
int d,x,y,ans;
int find(int x){
if(pre[x]==x)
return x;
int tmp=find(pre[x]);
rel[x]=(rel[x]+rel[pre[x]])%3;//rel[x]:x的根与x关系 1 x根吃x 2 x根被x吃
//rel[x]=1 rootx吃x rel[pre[x]]=2 rootxx被rootx吃 rootx吃rootxx x,rootxx同类0
return pre[x]=tmp;
}
void merge(int d,int x,int y){
int px=find(x),py=find(y);
if(px==py) //同根不用合并
{
if(d==1 && rel[x]!=rel[y])//x与y是同类时,此时要满足这要求,则必须满足p[x].relation=p[y].relation
ans++;
if(d==2 && (rel[y]-rel[x]+3)%3!=d-1) //x->y x->rootx(rooty)->y看偏移量是否==d-1
ans++;
return;
}
pre[py]=px; //rootx->x->y->rooty
rel[py]=(rel[x]-rel[y]+d-1+3)%3;
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++){
pre[i]=i;
rel[i]=0;
}
for(int i=1;i<=k;i++){
scanf("%d %d %d",&d,&x,&y);
if(x>n || y>n || (d==2 && x==y))
{
ans++;
continue;
}
merge(d,x,y);
}
cout<<ans<<endl;
return 0;
}
扩展域并查集写法
一定要开3倍空间150000=2e5 RE
特判x>n y>n 记得continue
else 走d=2 但同类xy同根 自己吃自己ans++
https://blog.csdn.net/bjfu170203101/article/details/89035824
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
#define IO ios::sync_with_stdio(false);cin.tie(0);
#define endl '\n'
const int maxn=2e5+5;
int n,k,d,x,y,ans;
int pre[maxn];
int find(int x){
if(pre[x]==x)
return x;
return pre[x]=find(pre[x]);
}
void merge(int x,int y){
int px=find(x),py=find(y);
pre[px]=py;
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=3*n;i++){
pre[i]=i;
}
for(int i=1;i<=k;i++){
scanf("%d %d %d",&d,&x,&y);
if(x>n || y>n){
ans++;
continue;
}
if(d==1)
{
if(find(x)==find(y+n) || find(x)==find(y+2*n))
ans++;
else{
merge(x,y);//同类域
merge(x+n,y+n);//天敌域
merge(x+2*n,y+2*n);//捕食域
}
}
else{//x同类域与y的天敌域同根
if(find(x)==find(y) || find(x)==find(y+2*n))//d=2时同类同根自己吃自己 x与y同类域 x与y捕食域同根
ans++;
else{
merge(x,y+n);//x同类域 y天敌域
merge(x+n,y+2*n);//x天敌 y捕食
merge(x+2*n,y);//x捕食 y同类 成环
}
}
}
printf("%d\n",ans);
return 0;
}