#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int M = 51000;
int par[M],rank[M],n;
// rank[x]={0,1,2} x和父节点关系 同类 吃 被吃;
int find(int x)
{
if(x!=par[x])
{
int t=par[x];
par[x]=find(par[x]);//路径压缩
rank[x]=(rank[x]+rank[t])%3; // 画个表格推一下咯~
}
return par[x];
}
void Union(int x,int y,int d) // x->y 关系为 d
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
par[fx]=fy; // fx->fy 关系?
rank[fx]=(3-rank[x]+d+rank[y])%3; //fx->x->y->fy
}
}
int main()
{
int n,k,d;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
par[i]=i;
}
int count=0;
for(int i=0;i<k;i++)
{
int x,y;
scanf("%d%d%d",&d,&x,&y);
if(x>n||x<1||y>n||y<1||(d==2&&x==y))
{
count++;
continue;
}
int rx=find(x);
int ry=find(y);
if(rx==ry) //两个元素在同一组 才可以可以判定之间的关系 。
{
// x->root r[x] 则root-> x 3-r[x]
// 当前x->y关系? 是否为 d-1?
// x->root->y (r[x]+3-r[y])%3
if((rank[x]+3-rank[y])%3 != d-1)
{
count++;
continue;
}
}
else
{
Union(x,y,d-1); //x->y d-1
}
}
cout<<count<<endl;
return 0;
}
poj 1182 带权并查集经典
最新推荐文章于 2020-12-02 20:27:44 发布