带权重的并查集(权重0代表与父节点同类,1为父节点食物即被父节点吃,2为吃父节点)
#include<bits/stdc++.h>
using namespace std;
int arr[50010],da[50010];//并查集数组和权重数组
int fi(int x)
{
if(arr[x]!=x)
{
int temp=arr[x];
arr[x]=fi(arr[x]);
da[x]=(da[temp]+da[x])%3;//路径压缩
return arr[x];
}
return x;
}
int main()
{
int n,k,op,x,y,ans=0;
cin>>n>>k;
for(int i=1;i<=n;i++) arr[i]=i;
for(int i=0;i<k;i++)
{
scanf("%d%d%d",&op,&x,&y);
if(op==2&&x==y) ans++;
else if(x>n||y>n) ans++;
else
{
int a=fi(x);
int b=fi(y);
if(op==1)
{
if(a!=b)
{
arr[b]=a;
da[b]= (3-da[y]+da[x])%3;
}
else if(a==b&&da[x]!=da[y]) ans++;
}
else
{
if(a!=b)
{
arr[b]=a;
da[b]= (3-da[y]+da[x]+1)%3;
}
else if(a==b&&(da[y]-da[x]+3)%3!=1) ans++;
}
}
}
cout<<ans<<endl;
}

京公网安备 11010502036488号