HDU4009 Transfer water 【最小树形图】
Transfer water
line from other household. If the household decide to dig a well, the money for the well is the height of their house multiplies X dollar per meter. If the household decide to build a water line from other household, and if the height of which supply water
is not lower than the one which get water, the money of one water line is the Manhattan distance of the two households multiplies Y dollar per meter. Or if the height of which supply water is lower than the one which get water, a water pump is needed except
the water line. Z dollar should be paid for one water pump. In addition,therelation of the households must be considered. Some households may do not allow some other households build a water line from there house. Now given the 3‐dimensional position (a, b,
c) of every household the c of which means height, can you calculate the minimal money the whole village need so that every household has water, or tell the leader if it can’t be done.
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 30
1 3 2
2 4 1
1 2
2 1 2
0 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|.
题意:给定n个点的三维坐标,以及根节点到每一个点的单向权值。再给定n个节点间相互单向连接的成本,求最小树形图。
题解:水源能够看作从虚拟根节点引出来的。这道题必然有解。由于大不了每一个实际点都跟根节点相连嘛,所以ZL_MST函数里的推断非根无入边节点能够忽略掉。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#define maxn 1002
#define maxm 1000002 int X, Y, Z;
struct Node{
int x, y, z;
} ver[maxn];
struct Node2{
int u, v, cost;
} E[maxm];
int in[maxn], hash[maxn], vis[maxn], pre[maxn]; int calDist(Node a, Node b){
return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z);
} __int64 ZL_MST(int root, int nv, int ne)
{
__int64 ans = 0;
int u, v, i, cnt;
while(true){
//0.初始化
for(i = 0; i < nv; ++i) in[i] = INT_MAX;
//1.找最小入边集
for(i = 0; i < ne; ++i){
u = E[i].u; v = E[i].v;
if(E[i].cost < in[v] && u != v){
in[v] = E[i].cost; pre[v] = u;
}
}
//2.找非根无入边点(略)。由于必然有解
//3.找环。加权,又一次标号
memset(hash, -1, sizeof(hash));
memset(vis, -1, sizeof(vis));
cnt = in[root] = 0;
for(i = 0; i < nv; ++i){
ans += in[i]; v = i;
while(vis[v] != i && v != root && hash[v] == -1){
vis[v] = i; v = pre[v];
}
if(v != root && hash[v] == -1){
for(u = pre[v]; u != v; u = pre[u])
hash[u] = cnt;
hash[v] = cnt++;
}
}
if(cnt == 0) return ans; //无环,算法完毕
for(i = 0; i < nv; ++i)
if(hash[i] == -1) hash[i] = cnt++;
//4.缩点,遍历每一条边,又一次构图
for(i = 0; i < ne; ++i){
v = E[i].v;
E[i].u = hash[E[i].u];
E[i].v = hash[E[i].v];
if(E[i].u != E[i].v) E[i].cost -= in[v];
}
//顶点数降低
nv = cnt; root = hash[root];
}
return ans;
} int main()
{
int n, i, a, b, id;
while(scanf("%d%d%d%d", &n, &X, &Y, &Z) != EOF && (n||X||Y||Z)){
for(i = 0; i < n; ++i)
scanf("%d%d%d", &ver[i].x, &ver[i].y, &ver[i].z);
for(i = id = 0; i < n; ++i){
scanf("%d", &a);
while(a--){
scanf("%d", &b);
E[id].cost = calDist(ver[i], ver[--b]) * Y;
if(ver[b].z > ver[i].z) E[id].cost += Z;
E[id].u = i; E[id++].v = b;
}
}
for(i = 0; i < n; ++i){
E[id].u = n; E[id].v = i;
E[id++].cost = ver[i].z * X;
}
printf("%I64d\n", ZL_MST(n, n + 1, id));
}
return 0;
}
HDU4009 Transfer water 【最小树形图】的更多相关文章
- HDU4009 Transfer water —— 最小树形图 + 不定根 + 超级点
题目链接:https://vjudge.net/problem/HDU-4009 Transfer water Time Limit: 5000/3000 MS (Java/Others) Me ...
- hdu4009 Transfer water 最小树形图
每一户人家水的来源有两种打井和从别家接水,每户人家都可能向外输送水. 打井和接水两种的付出代价都接边.设一个超级源点,每家每户打井的代价就是从该点(0)到该户人家(1~n)的边的权值.接水有两种可能, ...
- HDU 4009 Transfer water 最小树形图
分析:建一个远点,往每个点连建井的价值(单向边),其它输水线按照题意建单向边 然后以源点为根的权值最小的有向树就是答案,套最小树形图模板 #include <iostream> #incl ...
- HDOJ 4009 Transfer water 最小树形图
Transfer water Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) T ...
- POJ 3164 Command Network 最小树形图模板
最小树形图求的是有向图的最小生成树,跟无向图求最小生成树有很大的区别. 步骤大致如下: 1.求除了根节点以外每个节点的最小入边,记录前驱 2.判断除了根节点,是否每个节点都有入边,如果存在没有入边的点 ...
- HDU 4009——Transfer water——————【最小树形图、不定根】
Transfer water Time Limit:3000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64u Subm ...
- HDU 4009 Transfer water(最小树形图)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4009 题意:给出一个村庄(x,y,z).每个村庄可以挖井或者修建水渠从其他村庄得到水.挖井有一个代价, ...
- 最小树形图(hdu4009)
Transfer water Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) T ...
- HDU4009:Transfer water(有向图的最小生成树)
Transfer water Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)To ...
随机推荐
- SPOJ1812: LCS2 - Longest Common Substring II & BZOJ2946: [Poi2000]公共串
[传送门:SPOJ1811&BZOJ2946] 简要题意: 给出若干个字符串,求出这些字符串的最长公共子串 题解: 后缀自动机 这两道题的区别只是在于一道给出了字符串个数,一个没给,不过也差不 ...
- 利用Matlab自带的深度学习工具进行车辆区域检测与车型识别【Github更新!!!】(三)
前言 对前面的东西更新了一下.地方包括: 1.GUI的更新,更友好的用户界面 2.支持用手直接画车辆区域,并且识别出来 3.将proposal.detect.fine-grained classifi ...
- jquery批量绑定click事件
jquery批量绑定click事件: var selects = $(".public_select dd ul li"); debugger; /*$(".public ...
- Golang 在 Mac、Linux、Windows 下交叉编译
Golang 支持在一个平台下生成另一个平台可执行程序的交叉编译功能. Mac下编译Linux, Windows平台的64位可执行程序: CGO_ENABLED= GOOS=linux GOARCH= ...
- WebApp之H5登录注册
代码indexhtml <!DOCTYPE html> <html> <head> <meta charset="utf-8"> & ...
- JavaScript总结(4)
如何绑定事件 程序员可以编写代码,要求页面在发生了某些事件时调用相应的JavaScript语句或函数,这被称为事件的绑定.事件的绑定有3种方式.1)在HTML标记中直接声明,这是最常见的一种做法.语法 ...
- sql server 中查询数据库下有多少张表以及同义词等信息
--查询数据库有多少张表SELECT count(0) from sysobjects where xtype = 'u' 复制代码 解释:sysobjects系统对象表. 保存当前数据库的对象.如约 ...
- Python3基础笔记---re模块
参考博客: Py西游攻关之模块 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列 ...
- bzoj 1088 [SCOI2005] 扫雷
SCOI2005 扫雷 一道很有趣的(水)题 “这道题有四种解法,你知道么” 给你矩阵的第二列的数字,求出第一列雷有多少种可能的摆法. 不懂扫雷规则的自行按win+R然后输入winmine 思考过后我 ...
- sql查询 按照规定的顺序返回结果集。
DECODE函数 oracle 独有,功能强大.相当于 if else if IF 条件=值1 THEN RETURN(翻译值1)ELSIF 条件=值2 THEN RETURN(翻译值2) ..... ...