hdu 4009 Transfer water 最小树形图
来源:互联网 发布:股票涨停公式源码 编辑:程序博客网 时间:2024/06/05 18:48
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4009
题目大意:
在山上有N户人家,每家的坐标为(xi, yi, zi)。每户人家要吃水,要么自己打井,花费为A zi,要么从别人的家引水渠代价为B两家的曼哈顿距离,如果这家的海拔比供水的低,还要另外再买一个价值为C的水泵。问每家都有水吃的最低花费是多少。
每家都有水的目标一定能达成,大不了每家都打口井…
把所有能连水渠的两家连起来,就得到了一个有向图,答案一定一个森林。建立一个虚节点,向每个点连一条有向边,权值为在第i家挖井的代价,这样就把答案从森林变成了一棵树,求全图的一个最小树形图就是最低的代价。
学习了一下朱刘算法,算法思路还比较简单,实现起来很巧妙。算是一个模板吧。
#include<bits/stdc++.h>#define N 1100#define INF 0x3f3f3f3f#define M 1100000using namespace std;int pre[N],id[N],visit[N],in[N];struct node{ int u,v,cost;}edge[M];int zhuliu(int root,int n,int m){ int res=0,u,v; while(1) { for(int i=0;i<n;i++) in[i]=INF; for(int i=0;i<m;i++) if(edge[i].u!=edge[i].v&&edge[i].cost<in[edge[i].v]) { pre[edge[i].v]=edge[i].u; in[edge[i].v]=edge[i].cost; } for(int i=0;i<n;i++) if(i!=root&&in[i]==INF) return -1; int tn=0; memset(id,-1,sizeof(id)); memset(visit,-1,sizeof(visit)); in[root]=0; for(int i=0;i<n;i++) { res+=in[i]; v=i; while(visit[v]!=i&&id[v]==-1&&v!=root) { visit[v]=i; v=pre[v]; } if(v!=root&&id[v]==-1) { for(int u=pre[v];u!=v;u=pre[u]) id[u]=tn; id[v]=tn++; } } if(tn==0) break; for(int i=0;i<n;i++) if(id[i]==-1) id[i]=tn++; for(int i=0;i<m;) { v=edge[i].v; edge[i].u=id[edge[i].u]; edge[i].v=id[edge[i].v]; if(edge[i].u!=edge[i].v) edge[i++].cost-=in[v]; else swap(edge[i],edge[--m]); } n=tn; root=id[root]; } return res;}int n,x[N],y[N],z[N],a,b,c,cnt;void addedge(int u,int v,int cost){ edge[cnt].u=u; edge[cnt].v=v; edge[cnt++].cost=cost;}int main(){ while(~scanf("%d%d%d%d",&n,&a,&b,&c)&&n) { cnt=0; for(int i=1;i<=n;i++) { scanf("%d%d%d",&x[i],&y[i],&z[i]); addedge(0,i,a*z[i]); } for(int i=1;i<=n;i++) { int t; scanf("%d",&t); for(int j=0;j<t;j++) { int u; scanf("%d",&u); if(u==i) continue ; int cost=(abs(x[i]-x[u])+abs(y[i]-y[u])+abs(z[i]-z[u]))*b; if(z[i]<z[u]) addedge(i,u,cost+c); else addedge(i,u,cost); } } cout<<zhuliu(0,n+1,cnt)<<endl; }}
0 0
- Hdu 4009 Transfer water (最小树形图)
- [HDU 4009] Transfer water 最小树形图
- HDU - 4009 Transfer water(最小树形图)
- Hdu 4009 Transfer water【最小树形图】
- hdu 4009 Transfer water 最小树形图
- HDU 4009Transfer water 最小树形图
- HDU 4009 Transfer water【最小树形图】
- HDU 4009 Transfer water 最小树形图 朱刘算法
- HDU 4009 Transfer water(最小树形图)
- hdu 4009 Transfer water(不定根的最小树形图)
- HDU 4009 Transfer water 最小树形图(简单题)
- [HDU 4009] Transfer water (最小树形图)
- Hdu 4009 Transfer water 最小树形图(模板)
- HDU 4009 Transfer water(不定根最小树形图)
- HDU 4009 Transfer water(最小树形图)
- hdu 4009 Transfer water(最小树形图模板)
- Hdu 4009 Transfer water(最小树形图)
- HDU 4009 Transfer water(最小树形图)
- 算法复习 - 迷宫问题
- 算法复习 - Dijkstra算法(迪杰斯特拉算法)
- ajax详解教程
- 数据库和数据仓库
- 超好用的一些三方库及开发相关拓展链接整理(不断更新ing)
- hdu 4009 Transfer water 最小树形图
- linux su切换用户提示 Authentication failure的解决方法
- memset()与memcpy()函数及其作用
- 几个简单代码片段-- Google C++ style guide
- 总结下Android中Bitmap的应用方式
- ubuntu中shift键打不出特殊符号
- Android蒙逼之旅----初识这个鬼东西
- 前端构建实践01:用 Bower 管理前端依赖
- SPRING SECURITY 3.X 完整入门教程(转)