带权并查集 HDU - 3047
发布日期:2021-05-06 14:13:07 浏览次数:32 分类:精选文章

本文共 804 字,大约阅读时间需要 2 分钟。

题意: 一圈座位有n个,给出m组序号之间的关系,比如,1 2 150 代表2号坐在1号位置序号+150,看m组数据有多少组冲突的。

思路: 带权并查集模板。

#include
#include
#include
#include
#include
#include
#include
using namespace std;#define N 50010int f[N],n,m,val[N],cnt;int getf(int v){ if(f[v]==v) return v; int t=f[v]; f[v]=getf(f[v]);/*压缩路径*/ val[v]+=val[t];/*记录当前节点到祖先节点的权值和(在压缩路径的过程中,遍历到他的祖先,加上权值)*/ return f[v];}void marge(int u,int v,int s){ int t1=getf(u),t2=getf(v); if(t1!=t2) { f[t2]=t1;/*搞清楚节点之间的父子关系!!!*/ val[t2]=val[u]-val[v]+s;/*向量*/ } else if(val[v]!=val[u]+s)/*祖先相同,之间距离关系也应该正确,否则矛盾*/ cnt++;}int main(){ while(~scanf("%d%d",&n,&m)) { cnt=0; for(int i=1; i<=n; i++) f[i]=i,val[i]=0; int v,u,s; for(int i=1; i<=m; i++) { scanf("%d%d%d",&u,&v,&s); marge(u,v,s); } printf("%d\n",cnt); } return 0;}
上一篇:4 Values whose Sum is 0 POJ - 2785
下一篇:倍增法求LCA

发表评论

最新留言

很好
[***.229.124.182]2025年03月29日 16时41分32秒