经典的并查集,参考别人写出来的
代码如下
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
int p;
int r; //0为同类,1为被父亲吃,2为吃父亲;
}a[50009];
int Find(int x)
{
if(x==a[x].p) return x;
int temp=a[x].p;
a[x].p=Find(temp);
a[x].r=(a[x].r+a[temp].r)%3;
return a[x].p;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
int ans=0;
for(int i=1;i<=n;i++){
a[i].p=i;
a[i].r=0;
}
while(k--){
int d,x,y;
scanf("%d%d%d",&d,&x,&y);
if(x>n||y>n) {
ans++; continue;
}
if(d==2&&x==y) {
ans++; continue;
}
int root1=Find(x);
int root2=Find(y);
if(root1!=root2) {
a[root2].p=root1;
a[root2].r=(a[x].r+d-1+3-a[y].r)%3; //根连起来就不用再检查了,一定是正确的;
}
else{
if(d==1&&a[x].r!=a[y].r) {
ans++; continue;
}
if(d==2&&(3-a[x].r+a[y].r)%3!=d-1) {
ans++; continue;
}
}
}
printf("%d\n",ans);
}