并查集是维护“属于同一组”的数据结构,但是在本题中,并不是只有属于同一类的
的信息还有捕食关系的存在,那么显然普通的并查集肯定不行。
可以把并查集扩大,变为种类并查集!
用三倍的并查积的存各种动物的关系,一倍存本身,二倍存猎物,三倍存天敌。
易错:注意每一次操作的合并要写三个合并
代码 c or cpp
#include<bits/stdc++.h>
int n,k,i,f[200000],z,x,y,ans;
int findd(int x)//找祖宗函数
{
while(x!=f[x])
{
x=f[x];
}
return x;
}
void unity(int x,int y)//合并函数
{
f[findd(x)]=findd(y);
return ;
}
int main()
{
scanf("%d %d",&n,&k);
for(i=1;i<=3*n;i++)//初始化三倍并查集
{
f[i]=i;
}
for(i=1;i<=k;i++)
{
scanf("%d %d %d",&z,&x,&y);
if(x>n||y>n)//数据超出范围显然直接弹出
{
ans++;
continue;
}
if(z==1)
{
if(findd(x+n)==findd(y)||findd(x+2*n)==findd(y))//如果x和y是捕食关系显然也不行
{
ans++;
}
else
{
unity(x,y);//x和y是一个种类
unity(x+n,y+n);//x和y的猎物也是一个种类
unity(x+2*n,y+2*n);//x和y的天敌也是一个种类
}
}
else if(z==2)
{
if(findd(x)==findd(y)||findd(x+2*n)==findd(y))//如果x和y是一个种类或者y是x的天敌显然不行
{
ans++;
}
else
{
unity(x+n,y);//x的猎物是y
unity(x+2*n,y+n);//x的天敌是y的猎物
unity(x,y+2*n);//x是y的天敌
}
}
}
printf("%d",ans);
return 0;
}