HDU3038:带权并查集

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;
}

 

posted @ 2019-02-10 13:04  月光下の魔术师  阅读(28)  评论(0)    收藏  举报