P2024 [NOI2001]食物链
这个题是带权并查集的经典题——种类并查集
这个题一共有3个种类A,B,C。
那么我们就把并查集数组开到3倍,分别表示3个种类。
不同种类的点并查集连边说明吃与被吃的关系,相同种类的点连边表示同类关系。
#include <bits/stdc++.h>
#define N 50050
using namespace std;
int n,k,f[N*3],op,x,y,ans;
int find(int x){
return x==f[x]?x:f[x]=find(f[x]);
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=3*n;i++)
f[i]=i;
while(k--){
scanf("%d%d%d",&op,&x,&y);
if(x>n || y>n){
ans++;
continue;
}
if(op==1){
if(find(x)==find(y+n) || find(x+n)==find(y))
ans++;
else{
f[find(x)]=find(y);
f[find(x+n)]=find(y+n);
f[find(x+n+n)]=find(y+n+n);
}
}
else{
if(find(x)==find(y) || find(x+n)==find(y))
ans++;
else{
f[find(x)]=find(y+n);
f[find(x+n)]=find(y+n+n);
f[find(x+n+n)]=find(y);
}
}
}
printf("%d",ans);
return 0;
}