http://acm.hdu.edu.cn/showproblem.php?pid=3038 并查集权值应用
Posted 老板,来一盆泪流满面
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了http://acm.hdu.edu.cn/showproblem.php?pid=3038 并查集权值应用相关的知识,希望对你有一定的参考价值。
题意:[1-n]的区间,有m个询问,每个询问表示[e,f]的和是g,问一共有多少组矛盾
sum[i]表示i到根节点的和,求区间和用sum[f]-sum[e-1];
为了简化e--;
因为是并查集 要出来最前面的那个数
1.如果共同祖先相同 直接用sum[f]-sum[e]与给的值g相比较
2.,不是共同祖先包括两种
这种为y>x fa[y]=x; 所以 对应sum[y]=sum[e]+g-sum[f];
还有x>y 让fa[x]=y 所以对应 sum[x]=sum[f]-g-sum[e];
下面 代码
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<vector> #include<math.h> using namespace std; #define ll long long #define INF 0x3f3f3f3f #define maxn 10005 #define N 200005 int fa[N],sum[N]; int Find(int x) { if(x!=fa[x]) { int po=fa[x]; fa[x]=Find(fa[x]); sum[x]+=sum[po]; } return fa[x]; } int main() { int n,m,e,f,g; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0; i<=n; i++) { fa[i]=i; sum[i]=0; } int ans=0; while(m--) { scanf("%d%d%d",&e,&f,&g); e--; int x=Find(e);//查找这个点的父节点 int y=Find(f);if(x==y) { if(sum[f]-sum[e]!=g) ans++; } else if(x<y) { fa[y]=x; sum[y]=g+sum[e]-sum[f]; } else { fa[x]=y; sum[x]=sum[f]-g-sum[e]; } } printf("%d\\n",ans); } return 0; }
以上是关于http://acm.hdu.edu.cn/showproblem.php?pid=3038 并查集权值应用的主要内容,如果未能解决你的问题,请参考以下文章