240. 食物链
题目链接https://www.acwing.com/problem/content/242/
题目:
//并查集先更新头结点的距离,然后再更新下面的子节点。
//因为子节点的距离是相对于头结点的距离。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=5e4+10;
int p[N],ans=0,cnt[N];
int findd(int u){
if(p[u]!=u){
int t=findd(p[u]);
cnt[u]+=cnt[p[u]];
//并查集先更新头结点的距离,然后再更新下面的子节点。
//因为子节点的距离是相对于头结点的距离。
p[u]=t;
}
return p[u];
}
int main(){
int n,m;
cin>>n>>m;
int d,x,y;
for(int i=1;i<N;i++)
p[i]=i;
while(m--){
scanf("%d%d%d",&d,&x,&y);
if(x>n||y>n){
ans++;
continue;
}
int a=findd(x),b=findd(y);
if(d==1){
if(a!=b){
p[a]=b;
cnt[a]=cnt[y]-cnt[x];
}else if(a==b&&(cnt[x]-cnt[y])%3)
ans++;
}else{
if(a!=b){
p[a]=b;
cnt[a]=cnt[y]+1-cnt[x];
}else if(a==b&&(cnt[x]-cnt[y]-1)%3)
ans++;
}
}
cout<<ans;
return 0;
}