一种很巧妙的并查集思路:将一个并查集分为三个部分——
- x 代表自己
- x+n代表x的猎物
- x+n*2代表x的敌人
知道这些后事情就好办了:如果让两个物种同类,就判断两个物种是不是可以分别为猎物
如果让x吃y,就判断两个是否同族或者x是否为y的猎物
总结:最近第一次做题时思路还是太少了,还要多做啊~~~~
Code
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10;
int n,k,cnt;
int fa[N*3];
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void unit(int x,int y){
int xx=find(x),yy=find(y);
fa[yy]=xx;
}
int main (){
scanf("%d%d",&n,&k);
for(int i=1;i<=n*3;i++){
fa[i]=i;
}
for(int i=1;i<=k;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>n||c>n){
cnt++;
continue;
}
if(a==1){
if(find(b+n)==find(c)||find(b+n*2)==find(c)){
cnt++;
continue;
}
unit(b,c);unit(b+n,c+n);unit(b+n*2,c+n*2);
}
if(a==2){
if(find(c+n)==find(b)||find(c)==find(b)){
cnt++;
continue;
}
unit(b,c+n*2);unit(b+n,c);unit(b+2*n,c+n);
}
}
printf("%d",cnt);
}