这已经是我做的第三道加权并查集,感觉很顺手,只要在权值的设置方面画个草图,这种问题还是很简单的。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <cmath>
#include <algorithm>
#define N 200005
using namespace std;
int G[N],Rank[N],m,n,ans;
void Set()
{
for(int i=0;i<=n;i++)
{
G[i]=i;
Rank[i]=0;
}
ans=0;
}
int Find(int x)
{
if(G[x]==x) return x;
int t=G[x];
G[x]=Find(G[x]);
Rank[x]+=Rank[t];
return G[x];
}
void Union(int x,int y,int z)
{
int p=Find(x),q=Find(y);
if(p!=q)
{
if(p<q)
{
G[p]=q;
Rank[p]=Rank[y]-z-Rank[x];
}
else
{
G[q]=p;
Rank[q]=Rank[x]-Rank[y]+z;
}
}
else
{
if(Rank[x]+z!=Rank[y]) ans++;
}
}
int main()
{
int p,q,w;
while(scanf("%d %d",&n,&m)!=EOF)
{
Set();
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&p,&q,&w);
p--;
Union(p,q,w);
}
printf("%d\n",ans);
}
return 0;
}