带权并查集。
注意权在并和查中偏移的方式,结合向量来理解。
#include<cstdio>
struct one_node
{
int pre;
int rel;
}node[50001];
void init(int n)
{
for(int i=0;i<=n;i++)
{
node[i].pre=i;
node[i].rel=0;
}
}
int find(int x)
{
if(x!=node[x].pre)
{
int temp=node[x].pre;
node[x].pre=find(node[x].pre);
node[x].rel=(node[x].rel+node[temp].rel)%3;
}
return node[x].pre;
}
bool unin(int kind,int x,int y)
{
int rootx=find(x);
int rooty=find(y);
if(kind==1)
{
if(rootx==rooty)
{
if(node[x].rel==node[y].rel) return true;
else return false;
}
else
{
node[rooty].pre=rootx;
node[rooty].rel=(3-node[y].rel+node[x].rel)%3;
return true;
}
}
else if(kind==2)
{
if(rootx==rooty)
{
if((node[x].rel+(3-node[y].rel))%3==1) return true;
else return false;
}
else
{
node[rooty].pre=rootx;
node[rooty].rel=((3-node[y].rel)+3-1+node[x].rel)%3;
return true;
}
}
}
int main()
{
int n,k;
scanf("%d %d",&n,&k);
{
init(n);
int bed=0;
while(k--)
{
int kind,x,y;
scanf("%d %d %d",&kind,&x,&y);
if(x>n||x<1||y>n||y<1) {bed++; continue;}
if(unin(kind,x,y)==0) bed++;
}
printf("%d\n",bed);
}
return 0;
}