HDU 4009:Transfer water
来源:互联网 发布:网页淘宝自动跳转app 编辑:程序博客网 时间:2024/05/22 17:42
Transfer water
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 5171 Accepted Submission(s): 1860
First line of each case contains 4 integers n (1<=n<=1000), the number of the households, X (1<=X<=1000), Y (1<=Y<=1000), Z (1<=Z<=1000).
Each of the next n lines contains 3 integers a, b, c means the position of the i‐th households, none of them will exceeded 1000.
Then next n lines describe the relation between the households. The n+i+1‐th line describes the relation of the i‐th household. The line will begin with an integer k, and the next k integers are the household numbers that can build a water line from the i‐th household.
If n=X=Y=Z=0, the input ends, and no output for that.
2 10 20 301 3 22 4 11 22 1 20 0 0 0
30HintIn 3‐dimensional space Manhattan distance of point A (x1, y1, z1) and B(x2, y2, z2) is |x2‐x1|+|y2‐y1|+|z2‐z1|.
题目翻译:
问题描述:
小A住在一个村庄,去年洪水淹没了这个村庄。因此他们决定将整个村庄搬到附近的山上。山上没有泉水,因此每一家必须选择打一个井或者从别的人家引水。如果一家决定去挖一口井,则他们打井的费用是他们房子的高度,X每米。如果决定去引水,如果引水的地方比当前地方高,则引水的钱是这两家的距离成上Y美元每米。如果引水的地方比当前低。则必须需要水泵(除了引水线后)还要花费Z美元买一个水泵。除此之外,村民的关系是需要考虑的。一些村民不允许一些村民从他们的房子引水。现在给出3个实数(a,b,c)。每个房子的坐标。计算整个村庄都通上水的最小花费。如果不能,则输出不能。
输入:
多组测试数据.
第一行包含四个整数,n(家庭个数),X(自己选择打井每米的费用),Y(从高处往低处引水,Y美元每米),Z(一个水磅的价钱)。
接下来是N行,每行三个整数a,b,c,代表第i个房子的位置。
接下来N行,描述这些村民的关系。每行一个整数t,然后后面t个整数代表这t个节点都能从节点i引水。
题目规定这个三维空间两点的距离这样计算
Point A(x1,y1,z1)和 Point B(x2,y2,z2) 的距离这样算
abs(x1-x2)+abs(y1-y2)+abs(z1-z2)
输出:
如果能满足每户人家都能通上水,输出最小花费,否则输出
poor XiaoA
解题思路:
非常好的一道题目,用的还是朱刘算法求最小树形图。只存储边的关系。
因为每个节点可以考虑自己打井,也可以考虑从其他村民家引水,因此在哪里打井都不确定。这里有一个很巧妙的方法创建一个人工节点0,代表我在这个地方挖井不要钱。
然后我将0到其他节点的权值赋为在每个节点打井的费用。这一点思想和第八届河南省省赛题目:引水工程 求最小生成树的处理方法是一样的。
如果节点 i 能从节点 j 引水。如果节点 j 比节点 i 的高度低,则引水除了线路铺设费用,还要加上买水泵的钱。
建立图后。用以0为定跟,用朱刘算法求最小树形图即可。
#include <iostream>#include <string.h>#include <cstdio>#include <cmath>#define INF 0x3f3f3f3fusing namespace std;const int maxn = 1004;int N,X,Y,Z;///N是节点个数,X是每个家庭选择自己打井每米的费用。///Y是从别人家引水每米的费用,Z是一台水泵的价钱(从低处往高处引水要用水泵)struct pos ///每个村民家的三维坐标{ int x; int y; int z;}p[maxn];struct Edge{ int u; int v; long long int w;}edge[maxn*maxn];long long int Distance(struct pos p1,struct pos p2) ///题目定义三维两点距离这样计算{ return abs(p1.x-p2.x)+abs(p1.y-p2.y)+abs(p1.z-p2.z);}int closest[maxn],id[maxn],vis[maxn],in[maxn];long long int Min_Cost(int root,int NodeNum,int EdgeNum){ long long int ans = 0; int i; while(true) { ///1.求每个节点的最小入边权值 for(i = 0; i < NodeNum; i++) ///节点编号从0~N,总共N+1个点 in[i] = INF; for(i = 0; i < EdgeNum; i++) { int u = edge[i].u; int v = edge[i].v; if(u!=v && edge[i].w < in[v]) { in[v] = edge[i].w; closest[v] = u; } } for(i = 0; i < NodeNum; i++) { if(i == root) continue; if(in[i]==INF) return -1; } ///2.判断有无环。 int CNT = 0; memset(vis,-1,sizeof(vis)); memset(id,-1,sizeof(id)); in[root] = 0; for(i = 0; i < NodeNum; i++) { ans += in[i]; int v = i; while(v != root && vis[v]!=i && id[v]==-1) { vis[v] = i; v = closest[v]; } if(v != root && id[v]==-1) { for(int u = closest[v]; u != v; u = closest[u]) { id[u] = CNT; } id[v] = CNT++; } } if(CNT == 0) break; for(i = 0; i < NodeNum; i++) { if(id[i]==-1) id[i] = CNT++; } ///更新图 for(i = 0; i < EdgeNum; i++) { int u = edge[i].u; int v = edge[i].v; edge[i].u = id[u]; edge[i].v = id[v]; if(id[u] != id[v]) edge[i].w = edge[i].w - in[v]; } NodeNum = CNT; root = id[root]; } return ans;}int main(){ int t,node; while(~scanf("%d%d%d%d",&N,&X,&Y,&Z)) { if(N == 0 && X == 0 && Y == 0 && Z == 0) break; for(int i = 1; i <= N; i++) ///输入N个村民家的坐标 scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z); int k = 0; ///建立虚拟节点0,0到其他节点引水的权值是每个地方的打井费用 for(int i = 1; i <= N; i++) { edge[k].u = 0; edge[k].v = i; edge[k].w = X*p[i].z; k++; } for(int i = 1; i <= N; i++) { scanf("%d",&t); ///能从第i个村民家引水的家庭有t个 for(int j = 1; j <= t; j++) { scanf("%d",&node); edge[k].u = i; edge[k].v = node; edge[k].w = Distance(p[i],p[node])*Y; if(p[i].z < p[node].z) ///如果节点i比节点z的高度低,要买水泵 edge[k].w += Z; k++; } } long long int ans = Min_Cost(0,N+1,k); if(ans < INF) printf("%lld\n",ans); else printf("poor XiaoA\n"); } return 0;}
- 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【最小树形图】
- hdu 4009 Transfer water 最小树形图
- HDU 4009Transfer water 最小树形图
- HDU 4009 Transfer water【最小树形图】
- Transfer water HDU
- HDU 4009 Transfer water 最小树形图 朱刘算法
- HDU 4009 Transfer water(最小树形图)
- pyqt4原始例程--调用QtDesigner生成的子函数
- iBET Online Casino – XPG Live Casino Game Introduction(iBET, iBET Online Casino, Live Casino Game In
- 在数据库中,进行了插入数据,如果未commit就关掉数据库了
- Java反射三 构造方法
- 代码重构(一):函数重构规则
- HDU 4009:Transfer water
- 菩萨蛮.黄鹤楼
- 告诉孩子,我们为什么要读书?一位爸爸接地气的回答
- Android中的IPC机制
- C++:拷贝构造函数
- javaee学习笔记一
- Android的Volley框架实现获取cookie并同步到Webview的实现
- Activity的生命周期和启动模式
- idea webStorm license server 激活