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]。
盗用一张图:
View Code
思路:冲突的条件是:两个人坐在同一行,同时他们到根节点的差值等于他们之间的差值,这时就产生冲突了。于是我们可以用一个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
相关文章推荐
- HDU 3047 Zjnu Stadium(带权并查集,路径压缩)
- HDU 3047 带权并查集
- hdu 3047 带权并查集
- HDU 3047 Zjnu Stadium - 并查集
- hdu 3047(带权并查集)
- hdu 3047 Zjnu Stadium(加权并查集)2009 Multi-University Training Contest 14
- HDU 3047 Zjnu Stadium(带权并查集)
- hdu 3047(带权并查集)
- hdu 3047 Zjnu Stadium 带权并查集
- hdu 3047(扩展并查集)
- HDU 3047 Zjnu Stadium 带权并查集
- HDU 3047 Zjnu Stadium(带权并查集)
- Zjnu Stadium(hdu-3047)(带权并查集)
- hdu 3047 Zjnu Stadium【带权并查集】
- hdu 3047 (带权并查集)@
- HDU 3047 带权并查集
- HDU 3047 Zjnu Stadium(带权并查集)
- hdu 3047 Zjnu Stadium 并查集高级应用
- HDU 3047 带权并查集
- hdu 3047 带权并查集