我们先开所有种数倍大的数组,将该数组作为一个种类,每次合集的时候要操作相应多次。
如果a与n+b或者b与n+a有关系,就代表a和b有捕食关系(三种都有合并,判断一种即可),其中我们假设A吃B,B吃C,C吃A(X=A , n+X=B , 2*n+X=C),那么,如果x与n+y是同一个集,就代表了x吃了y(A吃B),若不是同类,就可以按顺序链接,这里我按指向食物来链接
代码
#include <bits/stdc++.h>
using namespace std;
int s[150005];
int find(int x)
{
if(s[x]==x) return x;
return s[x]=find(s[x]);
}
void combine(int x,int y)
{
s[find(y)]=find(x);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=3*n;i++) s[i]=i;
int res=0;
for(int i=0;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>n||c>n)
{
res++;
continue;
}
if(a==1)
{
if(find(b)==find(n+c)||find(c)==find(n+b)) res++;
else
{
combine(b,c);
combine(b+n,c+n);
combine(b+2*n,c+2*n);
}
}
else
{
if(find(b)==find(c)||find(c)==find(n+b)) res++;
else
{
combine(n+c,b);
combine(2*n+c,n+b);
combine(c,2*n+b);
}
}
}
cout<<res;
return 0;
}