hdu 3047 带权并查集
2013-01-14 12:15
155 查看
转自:http://www.cnblogs.com/newpanderking/archive/2012/10/31/2748567.html
分析:这是一道比较简单地并查集题目。
(1)弄清题意,找出出现冲突的位置,判断冲突很简单就是当两个人在同一行坐,同时他们到根节点的距离差值正好是他们之间的差值,此时就出现了冲突了。
(2)关键有两个地方,这也是并查集题目的难点,就是压缩集合,和求节点到根的距离。这里压缩集合就很简单了,一个通用的递归。求到跟的距离dist[a]+= dist[tem];
dist[rb]=dist[a]+x-dist[b];注意这两行代码,这是核心代码,首先第一行是求出节点a到根的距离。第二行代码使用的是数学中向量计算的原理如图
分析:这是一道比较简单地并查集题目。
(1)弄清题意,找出出现冲突的位置,判断冲突很简单就是当两个人在同一行坐,同时他们到根节点的距离差值正好是他们之间的差值,此时就出现了冲突了。
(2)关键有两个地方,这也是并查集题目的难点,就是压缩集合,和求节点到根的距离。这里压缩集合就很简单了,一个通用的递归。求到跟的距离dist[a]+= dist[tem];
dist[rb]=dist[a]+x-dist[b];注意这两行代码,这是核心代码,首先第一行是求出节点a到根的距离。第二行代码使用的是数学中向量计算的原理如图
/* 题目大意:有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的?? */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=50012; int n,m,fa[maxn],dis[maxn]; int find(int i) { if(fa[i]==i)return i; int ans=fa[i]; fa[i]=find(fa[i]); dis[i]+=dis[ans]; return fa[i]; } void Union(int u,int v,int fu,int fv,int x) { fa[fv]=fu; dis[fv]=dis[u]+x-dis[v]; } int main() { //freopen("//media/学习/ACM/input.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF) { int i,j,u,v,dist,ans=0,cnt=0; for(i=0;i<=n;i++)fa[i]=i,dis[i]=0; while(m--) { scanf("%d%d%d",&u,&v,&dist); int x=find(u),y=find(v); if(x!=y)Union(u,v,x,y,dist); else { if(dis[u]+dist!=dis[v]) ans++; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 3047 带权并查集
- HDU 3047 Zjnu Stadium 带权并查集
- HDU 3047 Zjnu Stadium(带权并查集)
- HDU 3047 排座位(带权值的并查集)
- hdu 3047 Zjnu Stadium(并查集)
- HDU 3047 带权并查集
- hdu 3047 Zjnu Stadium (带权并查集)
- HDU 3047 带权并查集
- HDU 3047 带权并查集
- HDU 3047 Zjnu Stadium(带权并查集,路径压缩)
- 【带权并查集】HDU 3047 Zjnu Stadium
- 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(扩展并查集)
- hdu 3047 Zjnu Stadium 带权并查集
- 【HDU 3047】 Zjnu Stadium 【带权并查集】