含【最小生成树Prim】模板。
Prim复杂度为$O(n^2),适用于稠密图,特别是完全图的最小生成树的求解。
 
Desert King
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions:31622   Accepted: 8670

Description

David the Great has just become the king of a desert country. To win the respect of his people, he decided to build channels all over his country to bring water to every village. Villages which are connected to his capital village will be watered. As the dominate ruler and the symbol of wisdom in the country, he needs to build the channels in a most elegant way.

After days of study, he finally figured his plan out. He wanted the average cost of each mile of the channels to be minimized. In other words, the ratio of the overall cost of the channels to the total length must be minimized. He just needs to build the necessary channels to bring water to all the villages, which means there will be only one way to connect each village to the capital.

His engineers surveyed the country and recorded the position and altitude of each village. All the channels must go straight between two villages and be built horizontally. Since every two villages are at different altitudes, they concluded that each channel between two villages needed a vertical water lifter, which can lift water up or let water flow down. The length of the channel is the horizontal distance between the two villages. The cost of the channel is the height of the lifter. You should notice that each village is at a different altitude, and different channels can't share a lifter. Channels can intersect safely and no three villages are on the same line.

As King David's prime scientist and programmer, you are asked to find out the best solution to build the channels.

Input

There are several test cases. Each test case starts with a line containing a number N (2 <= N <= 1000), which is the number of villages. Each of the following N lines contains three integers, x, y and z (0 <= x, y < 10000, 0 <= z < 10000000). (x, y) is the position of the village and z is the altitude. The first village is the capital. A test case with N = 0 ends the input, and should not be processed.

Output

For each test case, output one line containing a decimal number, which is the minimum ratio of overall cost of the channels to the total length. This number should be rounded three digits after the decimal point.

Sample Input

4
0 0 0
0 1 1
1 1 2
1 0 3
0

Sample Output

1.000

Source

题意:

有$n$个城市,每个城市有对应的坐标和海拔。两个城市之间的距离是坐标的距离,路的花费是海拔之差。

现在要建$n-1$条路,使得花费之和比距离之和最小。

思路:

一道0/1分数规划的题目。

0/1分数规划模型指:给定整数$a_1,a_2,...,a_n$,以及$b_1,b_2,...,b_n$,求一组解$x_i(1\leq i \leq n,x_i=0或1)$,

使得$\frac{\sum_{i=1}^{n} a_i*x_i}{\sum_{i=1}^{n}b_i*x_i}$最大化。

这种类型的题目我们可以通过二分答案来做。

因为如果对于$mid$,存在一组解,使得$\sum_{i=1}^{n}(a_i - mid * b_i) * x_i \geq 0$那么我们可以变形得到

存在一组解,使得$\frac{\sum_{i=1}^{n} a_i*x_i}{\sum_{i=1}^{n}b_i*x_i} \geq mid$

也就是说,$mid$比我们实际的答案要小。

反之,如果对于任意一组解,都有$\sum_{i=1}^{n}(a_i - mid * b_i) * x_i <0$那么我们可以得到

任意的解都有$\frac{\sum_{i=1}^{n} a_i*x_i}{\sum_{i=1}^{n}b_i*x_i} < mid$

也就是说,$mid$比我们实际的答案要大。

所以我们每次只需要计算$\sum_{i=1}^{n}(a_i - mid * b_i)*x_i$的最大值,如果最大值非负,令$st = mid$,否则$ed = mid$

对于这道题,也是类似。我们二分最终的答案。

每一次重新建图,城市和城市之间的边变为$cost - mid * length$

然后在新图上跑最小生成树。

如果最小生成树的值非负,说明实际答案比$mid$要大,令$st = mid$

由于这道题是完全图,而点的个数只有$1000$所以用prim比较好

WA了好久,后来发现是对d赋初值的问题。

对于double的数组赋初值$+\infty$不能用$0x3f$而应该用$0x7f$,就改了这里就过了。

 #include<iostream>
//#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
//#include<cstdlib>
#include<cstring>
#include<algorithm>
//#include<queue>
#include<vector>
//#include<set>
//#include<climits>
//#include<map>
using namespace std;
typedef long long LL;
#define N 100010
#define pi 3.1415926535
#define inf 0x3f3f3f3f const int maxn = ;
const double eps = 1e-;
int n;
struct city{
double x, y, height;
}c[maxn];
double dist[maxn][maxn], cost[maxn][maxn], g[maxn][maxn]; double get_dist(int i, int j)
{
return sqrt((c[i].x - c[j].x) * (c[i].x - c[j].x) + (c[i].y - c[j].y) * (c[i].y - c[j].y));
} double d[maxn];
bool vis[maxn];
void prim()
{
memset(d, 0x7f, sizeof(d));
memset(vis, , sizeof(vis));
/*for(int i = 1; i <= n; i++){
d[i] = (double)inf;
vis[i] = 0;
}*/
d[] = ;
for(int i = ; i <= n; i++){
int x = ;
for(int j = ; j <= n; j++){
if(!vis[j] && (x == || d[j] < d[x]))x = j;
}
vis[x] = ;
for(int y = ; y <= n; y++){
if(!vis[y])d[y] = min(d[y], g[x][y]);
}
}
} void getgraph(double mid)
{
for(int i = ; i <= n; i++){
for(int j = i; j <= n; j++){
g[i][j] = g[j][i] = cost[i][j] - mid * dist[i][j];
}
}
} bool check(double mid)
{
getgraph(mid);
prim();
double res = ;
for(int i = ; i <= n; i++){
res += d[i];
}
return res >= ;
} int main()
{
while(scanf("%d", &n) != EOF && n){
for(int i = ; i <= n; i++){
scanf("%lf%lf%lf", &c[i].x, &c[i].y, &c[i].height);
} for(int i = ; i <= n; i++){
for(int j = i; j <= n; j++){
dist[i][j] = dist[j][i] = get_dist(i, j);
cost[i][j] = cost[j][i] = fabs(c[i].height - c[j].height);
}
}
double st = 0.0, ed = 100.0;
while(ed - st >= eps){
double mid = (st + ed) / ;
if(check(mid))st = mid;
else ed = mid;
}
printf("%.3f\n", ed);
} return ;
}

poj2728 Desert King【最优比率生成树】【Prim】【0/1分数规划】的更多相关文章

  1. POJ2728 Desert King 最优比率生成树

    题目 http://poj.org/problem?id=2728 关键词:0/1分数规划,参数搜索,二分法,dinkelbach 参考资料:http://hi.baidu.com/zzningxp/ ...

  2. POJ2728 Desert King —— 最优比率生成树 二分法

    题目链接:http://poj.org/problem?id=2728 Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Subm ...

  3. POJ.2728.Desert King(最优比率生成树 Prim 01分数规划 二分/Dinkelbach迭代)

    题目链接 \(Description\) 将n个村庄连成一棵树,村之间的距离为两村的欧几里得距离,村之间的花费为海拔z的差,求花费和与长度和的最小比值 \(Solution\) 二分,假设mid为可行 ...

  4. POJ 2728 Desert King 最优比率生成树

    Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20978   Accepted: 5898 [Des ...

  5. 【POJ2728】Desert King 最优比率生成树

    题目大意:给定一个 N 个点的无向完全图,边有两个不同性质的边权,求该无向图的一棵最优比例生成树,使得性质为 A 的边权和比性质为 B 的边权和最小. 题解:要求的答案可以看成是 0-1 分数规划问题 ...

  6. Desert King(最优比率生成树)

    Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 22717   Accepted: 6374 Desc ...

  7. POJ 2728 Desert King(最优比率生成树, 01分数规划)

    题意: 给定n个村子的坐标(x,y)和高度z, 求出修n-1条路连通所有村子, 并且让 修路花费/修路长度 最少的值 两个村子修一条路, 修路花费 = abs(高度差), 修路长度 = 欧氏距离 分析 ...

  8. POJ 2728 Desert King (最优比率树)

    题意:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差,现在要求方案使得费用与距离的比值最小,很显然,这个题目 ...

  9. poj-2728Desert King(最优比率生成树)

    David the Great has just become the king of a desert country. To win the respect of his people, he d ...

  10. POJ 2728 Desert King (最优比例生成树)

    POJ2728 无向图中对每条边i 有两个权值wi 和vi 求一个生成树使得 (w1+w2+...wn-1)/(v1+v2+...+vn-1)最小. 采用二分答案mid的思想. 将边的权值改为 wi- ...

随机推荐

  1. Spring4学习笔记二:Bean配置与注入相关

    一:Bean的配置形式 基于XML配置:在src目录下创建 applicationContext.xml  文件,在其中进行配置. 基于注解配置:在创建bean类时,通过注解来注入内容.(这个不好,因 ...

  2. InnoDB 存储引擎的主要知识点介绍

    本文转载自:Draveness,略有修改 原文链接:『浅入浅出』MySQL 和 InnoDB · 面向信仰编程 作为一名开发人员,在日常的工作中会难以避免地接触到数据库,无论是基于文件的 sqlite ...

  3. zabbix server is not running,the information dispalyed may not be current

    查看zabbix服务器和客户端的端口及进程都是正常启动,打印的日志也没什么异常,但是就是在主页提示zabbix server is not running 不防尝试改一下zabbix_server的配 ...

  4. [转]关于ios 推送功能的终极解决

    刚刚做了一个使用推送功能的应用 遇到了一些问题整的很郁闷 搞了两天总算是弄明白了 特此分享给大家 本帖 主要是针对产品发布版本的一些问题 综合了网上一些资料根据自己实践写的 不过测试也可以看看 首先要 ...

  5. leetcode笔记:3Sum Closest

    一.题目描写叙述 二.解题技巧 该题与3Sum的要求类似.不同的是要求选出的组合的和与目标值target最接近而不一定相等.但实际上,与3Sum的算法流程思路类似,先是进行排序.然后顺序选择数组A中的 ...

  6. 菜鸟教程之工具使用(七)——从GIt上导出Maven项目

    今天继续我们的工具教程,公司用Git作为版本控制工具,所以最近一直在跟Git打交道.也是一边学习一边使用,于是想做一些入门教程,一来自己总结一下,二来还能帮助一些刚刚接触Git的朋友.一举两得,何乐而 ...

  7. 【Big Data - Hadoop - MapReduce】通过腾讯shuffle部署对shuffle过程进行详解

    摘要: 通过腾讯shuffle部署对shuffle过程进行详解 摘要:腾讯分布式数据仓库基于开源软件Hadoop和Hive进行构建,TDW计算引擎包括两部分:MapReduce和Spark,两者内部都 ...

  8. Hack mind

    试 卷 姓名________ 学号________ 首先我们来看这个,试卷的名字和编号填写,这个部分有“漏洞”吗?有 学生的姓名和编号都写在这儿,没有做任何保护措施,因此,你只要偷看了某人的试卷上的这 ...

  9. 新的时代:今日三款新IM正式宣战微信!

    今天(2019年1月5日)是社交圈的大日子,在今天上午将有三款不同的社交软件进行发布会,王欣.张一鸣.罗永浩旗下公司三款社交产品于今日同日发布. 新的时代,共同挑战微信 2019年1月15日,张一鸣的 ...

  10. ORA-00001: unique constraint (...) violated并不一定是数据冲突

    原文链接:http://blog.163.com/jet_it_life/blog/static/205097083201301410303931/ 收到一位测试人员RAISE的JIRA,说在某张表上 ...