原理
带权并查集和朴素并查集不同的是,带权并查集每个节点到根节点之间有一个权值,因此在路径压缩和合并操作时会有区别,具体代码通过下面的一个模板题给出.
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#define ll long long
using namespace std;
const int N=1e5+10
int n,m,par[N],val[N];
void init(){
for(int i=1;i<=n;i++){
par[i]=i;
val[i]=0;
}
}
int find(int x){
if(par[x]==x)
return x;
int p=par[x];
par[x]=find(par[x]); //路径压缩
val[x]+=val[p]; //更新x的权值
return par[x];
}
void unite(int x,int y,int w){ //合并操作
int xr=find(x),yr=find(y);
par[x]=yr;
par[xr]=yr;
val[xr]=val[y]+w-val[x]; //更新节点权值
val[x]=val[y]+w;
}
int main()
{
while(~scanf("%d%d",&n,&m)){
int ans=0,x,y,w;
init();
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&w);
int r1=find(x),r2=find(y);
if(r1!=r2)
unite(y,x,w);
else{
if(val[y]!=val[x]+w)
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}