题意:
给出一些信息 a b d 表示a点到b点的结点权值和等于d
问其中有多少组信息是错误的 一组信息和已经出现的信息不符就是错误的
种类并查集的关键在于找到根节点和子节点之间的关系
这里的vis[a]表示a点到根节点的距离
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define ll __int64
using namespace std;
int r[200005],vis[200005],n,m,d;
int ra,rb;
int root(int a)
{
if(r[a]==a) return a;
int tmp=r[a];
r[a]=root(r[a]);
vis[a]+=vis[tmp];
return r[a];
}
void merge(int a,int b)
{
if(ra<rb)
{
r[rb]=ra;
vis[rb]=vis[a]-d-vis[b];
}
else if(ra>rb)
{
r[ra]=rb;
vis[ra]=d+vis[b]-vis[a];
}
}
int main()
{
int a,b,i,ans;
while(~scanf("%d%d",&n,&m))
{
ans=0;
for(i=0;i<=n;i++)
r[i]=i;
memset(vis,0,sizeof vis);
while(m--)
{
scanf("%d%d%d",&a,&b,&d);
a--;
ra=root(a);
rb=root(b);
if(ra==rb&&vis[a]-vis[b]!=d)
{
ans++;
continue;
}
else if(ra!=rb)
{
merge(a,b);
}
}
printf("%d\n",ans);
}
return 0;
}