HDU3038:带权并查集
题解:带权并查集
简单的说,就是fx = fa[x],fy = fa[y],那么sum[x]即为区间[fx,x]的和,sum[y]即为区间[fy,y]的和
如果fx == fy,即左端点相同,我们就要判断sum[y]-sum[x]是否等于题目给的区间和
如果不相同,就要使fa[fy] = fx,此时sum[fy] = sum[y]+s-sum[x](三段区间的关系,大家自己想一下)
find函数和普通的并查集不一样,为了使结点指向父节点,区间和也要更新。
比如x指向y,y指向z,find函数路径压缩,使x指向z,此时sum[x]的区间和从[x,y]变成了[x,z]
#include <bits/stdc++.h>
using namespace std;
int const N = 2e5+7;
int n,m,fa[N],sum[N];
int find(int x){
if(x != fa[x]){
int t = fa[x];
fa[x] = find(fa[x]);
sum[x] += sum[t];
}
return fa[x];
}
int main(){
while(~scanf("%d%d",&n,&m)){
int ans = 0;
for(int i=0;i<=n;i++)
fa[i] = i,sum[i] = 0;
for(int i=1;i<=m;i++){
int l,r,s;
scanf("%d%d%d",&l,&r,&s);
--l;
int pl = find(l), pr = find(r);
if(pl != pr){
sum[pr] = s - sum[r] + sum[l];
fa[pr] = pl;
}else if(sum[r]-sum[l]!=s) ++ans;
}
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号