HDU4009 Transfer water —— 最小树形图 + 不定根 + 超级点
题目链接:https://vjudge.net/problem/HDU-4009
Transfer water
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 5612 Accepted Submission(s): 1997
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.
1 3 2
2 4 1
1 2
2 1 2
0 0 0 0
In 3‐dimensional space Manhattan distance of point A (x1, y1, z1) and B(x2, y2, z2) is |x2‐x1|+|y2‐y1|+|z2‐z1|.
代码一:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXM = 1e6+;
const int MAXN = 1e3+; struct Edge
{
int u, v, w;
}edge[MAXM]; int x[MAXN], y[MAXN], z[MAXN];
int pre[MAXN], id[MAXN], vis[MAXN], in[MAXN]; int zhuliu(int root, int n, int m)
{
int res = ;
while(true)
{
for(int i = ; i<n; i++)
in[i] = INF;
for(int i = ; i<m; i++)
if(edge[i].u!=edge[i].v && edge[i].w<in[edge[i].v])
{
pre[edge[i].v] = edge[i].u;
in[edge[i].v] = edge[i].w;
} for(int i = ; i<n; i++)
if(i!=root && in[i]==INF)
return -; int tn = ;
memset(id, -, sizeof(id));
memset(vis, -, sizeof(vis));
in[root] = ;
for(int i = ; i<n; i++)
{
res += in[i];
int v = i;
while(vis[v]!=i && id[v]==- && v!=root)
{
vis[v] = i;
v = pre[v];
}
if(v!=root && id[v]==-)
{
for(int u = pre[v]; u!=v; u = pre[u])
id[u] = tn;
id[v] = tn++;
}
}
if(tn==) break;
for(int i = ; i<n; i++)
if(id[i]==-)
id[i] = tn++; for(int i = ; i<m; )
{
int 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++].w -= in[v];
else
swap(edge[i], edge[--m]);
}
n = tn;
root = id[root];
}
return res;
} int main()
{
int n, m, X, Y, Z;
while(scanf("%d%d%d%d", &n, &X, &Y, &Z)!=EOF)
{
if(!n && !X && !Y && !Z) break; for(int i = ; i<n; i++)
scanf("%d%d%d", &x[i], &y[i], &z[i]); m = ;
for(int i = ; i<n; i++)
{
int num, v;
scanf("%d", &num);
while(num--)
{
scanf("%d", &v); v--;
edge[m].u = i;
edge[m].v = v;
edge[m].w = Y*(abs(x[i]-x[v])+abs(y[i]-y[v])+abs(z[i]-z[v]));
if(z[i]<z[v]) edge[m].w += Z;
m++;
}
//0~n-1为题目中的点, n为人工设置的超级点
//将超级点连到每一个结点,并且设置相应的权值
edge[m].u = n;
edge[m].v = i;
edge[m++].w = z[i]*X;
} int ans = zhuliu(n, n+, m);
printf("%d\n", ans);
}
}
代码二:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXM = 1e6+;
const int MAXN = 1e3+; struct Edge
{
int u, v, w;
}edge[MAXM]; int x[MAXN], y[MAXN], z[MAXN];
int pre[MAXN], id[MAXN], vis[MAXN], in[MAXN]; int zhuliu(int root, int n, int m)
{
int res = ;
while(true)
{
for(int i = ; i<n; i++)
in[i] = INF;
for(int i = ; i<m; i++)
if(edge[i].u!=edge[i].v && edge[i].w<in[edge[i].v])
{
pre[edge[i].v] = edge[i].u;
in[edge[i].v] = edge[i].w;
} for(int i = ; i<n; i++)
if(i!=root && in[i]==INF)
return -; int tn = ;
memset(id, -, sizeof(id));
memset(vis, -, sizeof(vis));
in[root] = ;
for(int i = ; i<n; i++)
{
res += in[i];
int v = i;
while(vis[v]!=i && id[v]==- && v!=root)
{
vis[v] = i;
v = pre[v];
}
if(v!=root && id[v]==-)
{
for(int u = pre[v]; u!=v; u = pre[u])
id[u] = tn;
id[v] = tn++;
}
}
if(tn==) break;
for(int i = ; i<n; i++)
if(id[i]==-)
id[i] = tn++; for(int i = ; i<m; i++)
{
int 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].w -= in[v];
}
n = tn;
root = id[root];
}
return res;
} int main()
{
int n, m, X, Y, Z;
while(scanf("%d%d%d%d", &n, &X, &Y, &Z)!=EOF)
{
if(!n && !X && !Y && !Z) break; for(int i = ; i<n; i++)
scanf("%d%d%d", &x[i], &y[i], &z[i]); m = ;
for(int i = ; i<n; i++)
{
int num, v;
scanf("%d", &num);
while(num--)
{
scanf("%d", &v); v--;
edge[m].u = i;
edge[m].v = v;
edge[m].w = Y*(abs(x[i]-x[v])+abs(y[i]-y[v])+abs(z[i]-z[v]));
if(z[i]<z[v]) edge[m].w += Z;
m++;
}
//0~n-1为题目中的点, n为人工设置的超级点
//将超级点连到每一个结点,并且设置相应的权值
edge[m].u = n;
edge[m].v = i;
edge[m++].w = z[i]*X;
} int ans = zhuliu(n, n+, m);
printf("%d\n", ans);
}
}
HDU4009 Transfer water —— 最小树形图 + 不定根 + 超级点的更多相关文章
- hdu4009 Transfer water 最小树形图
每一户人家水的来源有两种打井和从别家接水,每户人家都可能向外输送水. 打井和接水两种的付出代价都接边.设一个超级源点,每家每户打井的代价就是从该点(0)到该户人家(1~n)的边的权值.接水有两种可能, ...
- HDU2121 Ice_cream’s world II —— 最小树形图 + 不定根 + 超级点
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 Ice_cream’s world II Time Limit: 3000/1000 MS (J ...
- 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 ...
- HDU4009 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 ...
随机推荐
- Cannot delete or update a parent row: a foreign key constraint fails....
在操作”小弟“这张表时候报错 想在“小弟”上面加入数据或者更新数据,就要听老大的, 这句话后面跟着的表就是“老大”,必须老大有数据索引,“小弟“才可以加入或者更新 查看“小弟”表的外键,会发现有对“老 ...
- 【转】亿级Web系统搭建——单机到分布式集群
当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构层 ...
- Selenium加载Chrome/Firefox浏览器配置文件
Selenium启动浏览器时,默认是打开一个新用户,不会加载原有的配置以及插件.但有些时候我们可能需要加载默认配置. 一.Chrome浏览器 1.在Chrome浏览器的地址栏输入:chrome://v ...
- 大数据学习——hdfs客户端操作
package cn.itcast.hdfs; import org.apache.commons.io.IOUtils; import org.apache.hadoop.conf.Configur ...
- 大数据学习——yum安装tomcat
https://www.cnblogs.com/jtlgb/p/5726161.html 安装tomcat6 yum install tomcat6 tomcat6-webapps tomcat6-a ...
- @locked_cached_property ---flask.helpers模块
源码: class locked_cached_property(object): """A decorator that converts a function int ...
- [转载] Asynchronous ActionScript Execution
Asynchronous ActionScript Execution Date September 19, 2009 Language ActionScript 3.0 Target Flash P ...
- python多线程--线程同步
如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步. 使用Thread对象的Lock和Rlock可以实现简单的线程同步,这两个对象都有acquire ...
- Python基础教程笔记——第4章:字典
字典 字典是Python唯一内建的数学映射类型,字典中的值没有特殊的顺序,键可以是数字,字符串,甚至是元组 字典的创建: 字典由键值对构成,字典中键是唯一的,而值不唯一.>>> a_ ...
- Linux下出现launch failed.Binary not found的解决方案
Linux下出现launch failed.Binary not found的解决方案: Project->Properties->C/C++Build->Settings-> ...