父节点与子节点之间的关系,0为同类,1吃根节点,2被根节点吃
子为0,父子同类,父为0,父与根是同类,子与根(0+0)%3=0,子与根是同类;
子为1,子吃父,父为0,父与根是同类,子与根(1+0)%3=1,子吃根;
子为0,父子同类,父为1,父吃根,子与根(0+1)%3=1,子吃根;
子为1,子吃父,父为1,父吃根,子与根(1+1)%3=2,根吃子;
子为0,父子同类,父为2,根吃父,子与根(0+2)%3=2,根吃子;
子为1,子吃父,父为2,根吃父,子与根(1+2)%3=0,子与根是同类;
子为2,父吃子,父为2,根吃父,子与根(2+2)%3=1,子吃根;
子为2,父吃子,父为0,父与根是同类,子与根(2+0)%3=2,根吃子;
子为2,父吃子,
父为1,父吃根,子与根(2+1)%3=0,根与子是同类;
#include<stdio.h>
#include<algorithm>#include<iostream>
#include<string>
#include<string.h>
using namespace std;
int a[50002]; 点击打开链接
int b[50002];
void init(int n)
{
for(int i=1; i<=n; i++)
{
a[i]=i;
b[i]=0;//父节点与子节点之间的关系,0为同类,1吃根节点,2被根节点吃
}
}
int getf(int n)
{
if(n==a[n])
return n;
int t=getf(a[n]);
b[n]=(b[n]+b[a[n]])%3;//由父节点与子节点之间的关系,找父节点与根节点之间的关系
a[n]=t;
return a[n];
}
void merge(int x,int y,int d)
{
int t1,t2;
t1=getf(x);
t2=getf(y);
a[t2]=t1;
b[t2]=(b[x]-b[y]+3+(d-1))%3;//更新父节点与子节点之间的关系
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
init(n);
int sum=0;
int d,x,y;
while(k--)
{
scanf("%d%d%d",&d,&x,&y);
if(x>n||y>n||(d==2&&x==y))
{
sum++;
}
else if(getf(x)==getf(y))
{
if(d==1&&b[x]!=b[y])
{
sum++;
}
if(d==2&&(b[x]+1)%3!=b[y])
{
sum++;
}
}
else
merge(x,y,d);
}
printf("%d\n",sum);
return 0;
}