您的位置:首页 > 其它

hdu 3047(带权并查集)

2013-06-10 09:55 411 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3047

思路:冲突的条件是:两个人坐在同一行,同时他们到根节点的差值等于他们之间的差值,这时就产生冲突了。于是我们可以用一个dist数组来保存节点到根的距离,而这个距离在路径压缩的时候更新一下就可以了,dist[x]+=dist[parent[x]]。然后就是合并后的距离,令r1=Find(u),r2=Find(v),于是合并时就有parent[r2]=r1,dist[r2]=dist[u]+w-dist[v]。

盗用一张图:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 50000+50
int parent[MAXN];
int dist[MAXN];
int n,m,ans;

void Initiate()
{
memset(dist,0,sizeof(dist));
for(int i=0;i<=n;i++)
parent[i]=i;
}

int Find(int x)
{
if(x==parent[x])
return x;
int tmp=Find(parent[x]);
dist[x]+=dist[parent[x]];
return parent[x]=tmp;
}

int Union(int u,int v,int w){
int r1=Find(u),r2=Find(v);
if(r1==r2&&dist[v]!=dist[u]+w)return 1;
parent[r2]=r1;
dist[r2]=dist[u]+w-dist[v];
return 0;
}

int main()
{
int u,v,w;
while(~scanf("%d%d",&n,&m))
{
Initiate();
ans=0;
while(m--){
scanf("%d%d%d",&u,&v,&w);
if(Union(u,v,w))ans++;
}
printf("%d\n",ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: