[HDU 4009] Transfer water (最小树形图)
来源:互联网 发布:中年女士双肩背包 知乎 编辑:程序博客网 时间:2024/06/05 18:58
Transfer water
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4009
题目大意:
在一个小镇里面,有N户人家,每户人家的地址为(x,y,z)。现在要建立一个水循环系统,其中建立一个水井的费用与地址的高度成正比,即为X*z。而从一户有水井的人家接水到自己家的费用为:(|x2-x1| + |y2-y1| + |z2-z1|) * Y。当有水井的房子高度比其低时,需要加额外的Z元抽水费。
而且每户人家只允许自己的好友从自己家接水。现在问最小费用为多少
解题思路:
可以假想出一个房子0,并且只有0有水井。那么对于每户人家,如果要自己打水,那么相当于从0处接水。题目就变成了求有向图的最小树形图。
#include<iostream>#include<fstream>#include<cstdio>#include<cstring>#include<cmath>#include<map>#include<queue>#include<stack>#include<vector>#include<set>#include<ctype.h>#include<algorithm>#include<string>#define PI acos(-1.0)#define maxn 1100#define INF 1<<25#define mem(a, b) memset(a, b, sizeof(a))typedef long long ll;typedef int type;using namespace std;int n, X, Y, Z, m;struct point{ int x, y, z;}p[maxn];struct node{ int u, v; type w;}e[maxn * maxn];type dis(point a, point b){ return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z);}int pre[maxn], id[maxn], vis[maxn];type in[maxn];type Directed_MST(int root, int NV, int NE){ type ret = 0; while(true) { for (int i = 0; i < NV; i++) in[i] = INF; for (int i = 0; i < NE; i++) { int u = e[i].u, v = e[i].v; if (e[i].w < in[v] && u != v) { pre[v] = u; in[v] = e[i].w; } } for (int i = 0; i < NV; i++) { if (i == root) continue; if (in[i] == INF) return -1; } int cntcode = 0; mem(id, -1), mem(vis, -1); in[root] = 0; for (int i = 0; i < NV; i++) { ret += in[i]; int v = i; while(vis[v] != i && id[v] == -1 && v != root) { vis[v] = i; v = pre[v]; } if (v != root && id[v] == -1) { for (int u = pre[v]; u != v; u = pre[u]) id[u] = cntcode; id[v] = cntcode++; } } if (!cntcode) break; for (int i = 0; i < NV; i++) if (id[i] == -1) id[i] = cntcode++; for (int i = 0; i < NE; i++) { int v = e[i].v; e[i].u = id[e[i].u]; e[i].v = id[e[i].v]; if (e[i].u != e[i].v) e[i].w -= in[v]; } NV = cntcode; root = id[root]; } return ret;}int main (){ while(scanf("%d%d%d%d", &n, &X, &Y, &Z) != EOF) { if (n + X + Y + Z == 0) break; m = 0; for (int i = 1; i <= n; i++) { scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z); e[m].u = 0, e[m].v = i, e[m++].w = p[i].z * X; } for (int i = 1; i <= n; i++) { int k, d; scanf("%d", &k); while(k--) { scanf("%d", &d); e[m].u = i, e[m].v = d, e[m].w = dis(p[i], p[d]) * Y; if (p[i].z < p[d].z) e[m].w += Z; m++; } } type ans = Directed_MST(0, n + 1, m); if (ans == -1) puts("poor XiaoA"); else printf("%d\n", ans); } return 0;}
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 最小树形图 朱刘算法
- Python_C3_变量【中】
- 虚拟化的逆袭:OpenFlow和SDN
- 常用网络相关命令
- Linux rpm 命令参数使用详解[介绍和应用]
- Ubuntu10.10的网络配置
- [HDU 4009] Transfer water (最小树形图)
- HDU1050 Moving Tables
- 最小公倍数
- [转]多CPU程序开发: OpenMP-MPI(机群)和CUDA(GPU)
- [POJ 1985] Cow Marathon (树的直径)
- Let the Balloon Rise
- 反转链表
- avcodec_decode_video2()解码视频后丢帧的问题解决
- 为什么在头文件中有extern "C" ? .