HDU 4009 Transfer water(最小树形图)
2016-03-13 20:47
411 查看
Description
给出n户人家的位置(xi,yi,zi),一户人家可以别人家引进水源,也可以自己凿井,第一种方案的花费是两家哈密顿距离*Y,如果该户人家的海拔比引进水源的人家高,那么还有额外花费Z,第二种方案的花费是该户人家的海拔*X,问使得所有人家都有水的最小花费是多少,如果没有满足条件的方案则输出poor xiaoA
Input
多组用例,每组用例第一行为四个整数n,X,Y,Z,之后n行每行三个整数表示该户人家的坐标,之后n行每行首先输入一个整数num表示该户人家可以供水的人家数量,之后num个整数表示该户人家可以供水的人家编号,以0 0 0 0结束输入
Output
对于每组用例,如果存在可行方案则输出最小花费,否则输出”poor xiaoA”
Sample Input
2 10 20 30
1 3 2
2 4 1
1 2
2 1 2
0 0 0 0
Sample Output
30
Solution
在有供水关系的人家间建边,构造超级源点0,从0向每户人家i建zi*X的边表示该户人家自己凿井的花费,之后就是求这张图的最小树形图了
Code
给出n户人家的位置(xi,yi,zi),一户人家可以别人家引进水源,也可以自己凿井,第一种方案的花费是两家哈密顿距离*Y,如果该户人家的海拔比引进水源的人家高,那么还有额外花费Z,第二种方案的花费是该户人家的海拔*X,问使得所有人家都有水的最小花费是多少,如果没有满足条件的方案则输出poor xiaoA
Input
多组用例,每组用例第一行为四个整数n,X,Y,Z,之后n行每行三个整数表示该户人家的坐标,之后n行每行首先输入一个整数num表示该户人家可以供水的人家数量,之后num个整数表示该户人家可以供水的人家编号,以0 0 0 0结束输入
Output
对于每组用例,如果存在可行方案则输出最小花费,否则输出”poor xiaoA”
Sample Input
2 10 20 30
1 3 2
2 4 1
1 2
2 1 2
0 0 0 0
Sample Output
30
Solution
在有供水关系的人家间建边,构造超级源点0,从0向每户人家i建zi*X的边表示该户人家自己凿井的花费,之后就是求这张图的最小树形图了
Code
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; #define INF 0x3f3f3f3f #define maxn 1111 struct Edge { int u,v,c; }edge[maxn*maxn]; int pre[maxn],id[maxn],vis[maxn],in[maxn]; int zhuliu(int root,int n,int m) { int ans=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].c<in[edge[i].v]) { pre[edge[i].v]=edge[i].u; in[edge[i].v]=edge[i].c; } for(int i=0;i<n;i++) if(i!=root&&in[i]==INF) return -1; int res=0; memset(vis,-1,sizeof(vis)); memset(id,-1,sizeof(id)); in[root]=0; for(int i=0;i<n;i++) { ans+=in[i]; v=i; while(vis[v]!=i&&id[v]==-1&&v!=root) { vis[v]=i; v=pre[v]; } if(id[v]==-1&&v!=root) { for(u=pre[v];u!=v;u=pre[u]) id[u]=res; id[v]=res++; } } if(res==0)break; for(int i=0;i<n;i++) if(id[i]==-1) id[i]=res++; 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++].c-=in[v]; else swap(edge[i],edge[--m]); } n=res; root=id[root]; } return ans; } struct node { int x,y,z; }p[maxn]; int get_dis(node a,node b) { return abs(a.x-b.x)+abs(a.y-b.y)+abs(a.z-b.z); } int main() { int n,m,X,Y,Z; while(scanf("%d%d%d%d",&n,&X,&Y,&Z),n) { for(int i=1;i<=n;i++)scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z); m=0; for(int i=1;i<=n;i++) { int num,j; scanf("%d",&num); while(num--) { scanf("%d",&j); edge[m].u=i,edge[m].v=j,edge[m].c=get_dis(p[i],p[j])*Y; if(p[j].z>p[i].z)edge[m].c+=Z; m++; } } for(int i=1;i<=n;i++) edge[m].u=0,edge[m].v=i,edge[m++].c=p[i].z*X; int ans=zhuliu(0,n+1,m); if(ans!=-1)printf("%d\n",ans); else printf("poor XiaoA\n"); } return 0; }
相关文章推荐
- JavaScript语言精粹(读书笔记)
- 用于主题检测的临时日志(ba86b8a0-7ed7-4b0b-bf1f-ce41aa2a5780 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)
- 欢迎使用CSDN-markdown编辑器
- 四种参数传递的形式——URL,超链接,js,form表单
- Mac安装Caffe教程
- JavaScript基础篇(一)— — 基础
- caffe*** Aborted at 1457505270 (unix time) try "date -d @1457505270" if you are using GNU date ***
- Caffe做分类初步学习以及遇到的一些坑
- Caffe学习笔记(OCR字符识别)
- JSP与servlet之间的传值方式
- 11. jsp与servlet之间页面跳转及参数传递实例
- jsp页面间的传值方法
- 浏览器中的javaScript
- html中文乱码问题的解决
- "undefined reference to" 问题解决方法
- 前端工程与性能优化
- js实现放大镜效果
- Ubuntu14.04上深度学习Caffe库安装指南(CUDA7.5 + opencv3.1)
- html中js实现左边框控制右边框的显示
- JSP