【POJ - 2728】Desert King (最有比率生成树,分数规划)

题干:

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

题目大意:

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

一句话题意:

解题报告:

除了二分,还有一种算法叫Dinkelbach算法

每次将r'代入z函数中计算以后,我们将得到一组x

让r''=(∑(ci*xi))/(∑(di*xi))

当r''=r'时,r''就是我们需要的解

否则将r'=r'',继续迭代

这种方法比二分法要快一点

AC代码:(迭代法)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
int n;
const double eps = 1e-5;
struct Node {double x,y,z;
} node[MAX];
struct NN {int u,v;double x,y;
} ee[20 * MAX];
struct Edge {int u,v;double x,y,w;
} e[20 * MAX];
int f[MAX];
int tot;
bool cmp(Edge a,Edge b) {return a.w < b.w;
}
int getf(int v) {return f[v] == v ? v : f[v] = getf(f[v]);
}
void merge(int u,int v) {int t1 = getf(u);int t2 = getf(v);f[t2] = t1;
}
void init() {for(int i = 1; i<=n; i++) f[i] = i;
}
double kls() {sort(e+1,e+tot+1,cmp);init();int cnt = 0;double xx = 0,yy = 0;for(int i = 1; i<=tot; i++) {if(getf(e[i].u) != getf(e[i].v)) {xx += e[i].x;yy += e[i].y;cnt ++;merge(e[i].u,e[i].v);if(cnt == n - 1) break;}}return xx/yy;
}
double ok(double mid) {for(int i = 1; i<=tot; i++) e[i].u = ee[i].u,e[i].v = ee[i].v,e[i].x = ee[i].x,e[i].y = ee[i].y,e[i].w = ee[i].x - mid*ee[i].y;double res = kls();return res;
}
int main()
{while(~scanf("%d",&n)) {if(n == 0) break;tot = 0;//init() for(int i = 1; i<=n; i++) f[i] = i;for(int i = 1; i<=n; i++) {scanf("%lf%lf%lf",&node[i].x,&node[i].y,&node[i].z);}for(int i = 1; i<=n; i++) {for(int j = 1; j<i; j++) {ee[++tot].y = sqrt((node[i].x-node[j].x)*(node[i].x-node[j].x) + (node[i].y-node[j].y)*(node[i].y-node[j].y));ee[tot].x = fabs(node[i].z - node[j].z);ee[tot].u = i;ee[tot].v = j;}	}double l = 0,r = 1e9;
//		double mid = (l+r)/2,ans=mid;
//		while(l+eps < r) {
//			mid = (l+r)/2;
//			if(ok(mid)) r = mid;
//			else l = mid;
//		}double mid = (l+r)/2,ans = -1;while(fabs(ans-mid) >= eps) {ans = mid;mid = ok(mid);}printf("%.3f\n",ans - eps);}return 0 ;}

TLE代码:(二分)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
int n;
const double eps = 1e-5;
struct Node {double x,y,z;
} node[MAX];
struct NN {int u,v;double x,y;
} ee[20 * MAX];
struct Edge {int u,v;double w;
} e[20 * MAX];
int f[MAX];
int tot;
bool cmp(Edge a,Edge b) {return a.w < b.w;
}
int getf(int v) {return f[v] == v ? v : f[v] = getf(f[v]);
}
void merge(int u,int v) {int t1 = getf(u);int t2 = getf(v);f[t2] = t1;
}
void init() {for(int i = 1; i<=n; i++) f[i] = i;
}
double kls() {sort(e+1,e+tot+1,cmp);init();int cnt = 0;double res = 0;for(int i = 1; i<=tot; i++) {if(getf(e[i].u) != getf(e[i].v)) {res += e[i].w;cnt ++;merge(e[i].u,e[i].v);if(cnt == n - 1) break;}}return res;
}
bool ok(double mid) {for(int i = 1; i<=tot; i++) e[i].u = ee[i].u,e[i].v = ee[i].v,e[i].w = ee[i].x - mid*ee[i].y;double res = kls();if(res <=0) return 1;else return 0 ;
}
int main()
{while(~scanf("%d",&n)) {if(n == 0) break;tot = 0;init();for(int i = 1; i<=n; i++) {scanf("%lf%lf%lf",&node[i].x,&node[i].y,&node[i].z);}for(int i = 1; i<=n; i++) {for(int j = 1; j<i; j++) {ee[++tot].y = sqrt((node[i].x-node[j].x)*(node[i].x-node[j].x) + (node[i].y-node[j].y)*(node[i].y-node[j].y));ee[tot].x = fabs(node[i].z - node[j].z);ee[tot].u = i;ee[tot].v = j;}	}double l = 0,r = 1e9;double mid = (l+r)/2;while(l+eps < r) {mid = (l+r)/2;if(ok(mid)) r = mid;else l = mid;}printf("%.3f\n",mid - eps);}return 0 ;}

AC代码:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux非权限安装bioperl,bioperl的安装

1. 对于UNIX用户(1)下载BioPerl的源代码&#xff0c;并解压。我提供两个网址&#xff1a;(2)进入该目录&#xff0c;然后执行下列命令&#xff1a;$ perl Build.PL$ ./Build test# ./Build install (注意&#xff1a;执行./Build install时必须要有系统管理员权限)BioPerl和许多…

【牛客 - 327G】处女座与复读机(可编辑距离问题,dp)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/327/G 来源&#xff1a;牛客网 一天&#xff0c;处女座在牛客算法群里发了一句“我好强啊”&#xff0c;引起无数的复读&#xff0c;可是处女座发现复读之后变成了“处女座好强啊”。处女座经过调查…

linux远程打开windows程序,为新手讲解Linux和Windows系统的远程桌面访问知识

很多新手都是使用Linux和Windows双系统的&#xff0c;它们之间的远程桌面访问是如何连接的&#xff0c;我们就为新手讲解Linux和Windows系统的远程桌面访问知识&#xff0c;包括所使用的软件及方法。本文所使用的Linux版本是深度操作系统&#xff0c;如果要安装该版本请参考U盘…

【51nod - 1174 】区间中最大的数(RMQ问题,ST表,模板)

题干&#xff1a; 给出一个有N个数的序列&#xff0c;编号0 - N - 1。进行Q次查询&#xff0c;查询编号i至j的所有数中&#xff0c;最大的数是多少。 例如: 1 7 6 3 1。i 1, j 3&#xff0c;对应的数为7 6 3&#xff0c;最大的数为7。&#xff08;该问题也被称为RMQ问题&am…

linux用户登录实验,Linux用户和组相关命令及实验

本文简要介绍了在Linux系统下&#xff0c;如何对账户和组进行增、删、改的操作。一、 groupaddgroupadd [选项] group_name-g GID&#xff1a;指定GID&#xff1b;默认是上一个组的GID1&#xff1b;-r: 创建系统组&#xff1b;二、 groupmod命令&#xff1a;修改组属性groupmod…

【CSU - 1980 】不堪重负的树(树上区间dp)

题干&#xff1a; 小X非常喜欢树&#xff0c;然后他生成了一个大森林给自己玩。 玩着玩着&#xff0c;小X陷入了沉思。 一棵树由N个节点组成&#xff0c;编号为i的节点有一个价值Wi。假设从树根出发前往第i个节点&#xff08;可能是树根自己&#xff09;&#xff0c;一共需要…

linux windows 域,linux加入windows域之完美解决方案

《linux加入windows域之完美解决方案》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《linux加入windows域之完美解决方案(10页珍藏版)》请在人人文库网上搜索。1、linux加入windows域的理想方案原文来源&#xff1a; http:/rainbird.blog.51cto.com/笔者最近几天正在…

【蓝桥杯官网试题 - 算法训练 】K好数(线性dp与优化)

题干&#xff1a; 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字&#xff0c;那么我们就说这个数是K好数。求L位K进制数中K好数的数目。例如K 4&#xff0c;L 2的时候&#xff0c;所有K好数为11、13、20、22、30、31、33 共7个。由于这个数目很大…

arm-linux配置dhcp自动获取ip地址,ARM-Linux配置DHCP自动获取IP地址

备注&#xff1a;内核版本&#xff1a;2.6.30.9busybox版本&#xff1a;1.15.2PC Linux和开发板Linux的工作用户&#xff1a;root1. 配置内核&#xff1a;[*] Networking support --->Networking options --->Packet socketUnix domain sockets[*] TCP/IP networking[*…

【CodeForces - 897D】Ithea Plays With Chtholly (交互题型,贪心,思维构造,题目信息)

题目大意&#xff1a; This is an interactive problem. Refer to the Interaction section below for better understanding. Ithea and Chtholly want to play a game in order to determine who can use the kitchen tonight. Initially, Ithea puts n clear sheets of pa…

红帽子linux生效环境变量,RedHat Linux 5无法使用ifconfig的解决方法

ifconfig是Linux显示网络设备的命令&#xff0c;能够设置网络设备的状态&#xff0c;但在RedHat Linux 5系统中&#xff0c;有时会遇到ifconfig命令无法使用的情况&#xff0c;下面小编就给大家介绍下RedHat Linux 5无法使用ifconfig命令的解决方法。一起去看看吧&#xff01;在…

关于交互题---Idleness limit exceeded(codeforces)

Idleness limit exceeded的中文&#xff1a;懒惰超过限制。----来自有道翻译 大概意思是在该输出的情况下没有输出数据 比如这个&#xff1a; 而且一般都会提醒你&#xff1a;&#xff08;在每条输出之后加&#xff09; After outputting each line, dont forget to flush t…

Linux如何搭建服务器eb,Linux下CRMEB环境搭建

环境准备:PHP7.0.33MySQL5.7Apache2.4PHP环境安装:sudo apt-get install php-pear php7.0-cli php7.0-common php7.0-curl \php7.0-dev php7.0-fpm php7.0-json php7.0-mbstring php7.0-mcrypt \php7.0-mysql php7.0-opcache php7.0-zip php7.0-intl php7.0-gd php7.0-xmlMySQL…

【EOJ Monthly 2019.02 - A】回收卫星(交互题型,二分)

题干&#xff1a; 单测试点时限: 1.0 秒 内存限制: 256 MB “这个世上没有无用的齿轮&#xff0c;也只有齿轮本身能决定自己的用途。” 就像太空中的卫星&#xff0c;虽然不计其数&#xff0c;但都各司其职。 但没有一个东西是能够永远无损的。为了便于回收及修理&#xf…

windows 调用linux .a lib,动态链接库及静态链接库(windows下的.dll .lib和linux下的.so .a)...

动态链接库及静态链接库(windows下的.dll .lib和linux下的.so .a) 库有动态与静态两种&#xff0c;动态通常用.so为后缀&#xff0c;静态用.a为后缀。例如&#xff1a;libhello.so libhello.a 为了在同一系统中使用不同版本的库&#xff0c;可以在库文件名后加上版本号为后缀,例…

【EOJ Monthly 2019.02 - B】解题(思维,抽屉原理,暴力,模运算,优化,tricks)

题干&#xff1a; 单测试点时限: 2.0 秒 内存限制: 1024 MB “我把房门上锁&#xff0c;并非为了不让她进去&#xff0c;而是为了防止自己逃到她身边”。 她又被数学难住了。QQ 小方当然是不会对女生说”不”的。 她的数学题是这样的&#xff0c;她得到了一个十进制大整数…

linux socket ip层配置,Linux下Socket通信(TCP实现)

近期在做的项目中&#xff0c;涉及到了进程间数据传输&#xff0c;系统的原本实现是通过管道&#xff0c;但是原有的实现中两个进程是在同一台机器&#xff0c;而且两个进程的关系为父子关系&#xff0c;而我们要做的是将其中一个进程移植到服务器上&#xff0c;因此两个进程要…

【EOJ Monthly 2019.02 - D】进制转换(思维,取模,高精度大数)

题干&#xff1a; 单测试点时限: 2.0 秒 内存限制: 256 MB “他觉得一个人奋斗更轻松自在。跟没有干劲的人在一起厮混&#xff0c;只会徒增压力。” QQ 小方决定一个人研究研究进制转换。 很快&#xff0c;QQ 小方就遇到问题了。他现在想知道在十进制范围 [l,r] 内有多少整…

linux i2c触摸屏驱动程序,触摸屏i2c设备和驱动的创建流程及方法

添加i2c设备的流程&#xff1a;1. 初始化 i2c_board_info 结构信息 和 i2c_driver 结构//设备驱动结构体static struct i2c_driver goodix_ts_driver {.probe goodix_ts_probe,.remove goodix_ts_remove,#ifndef CONFIG_HAS_EARLYSUSPEND.suspend goodix_ts_su…

【EOJ Monthly 2019.02 - E】中位数(二分 ,中位数 ,−1/1变换,dp求解DAG最长路)

题干&#xff1a; E. 中位数 单测试点时限: 10.0 秒 内存限制: 256 MB “你的地图是一张白纸&#xff0c;所以即使想决定目的地&#xff0c;也不知道路在哪里。” QQ 小方最近在自学图论。他突然想出了一个有趣的问题&#xff1a; 一张由 n 个点&#xff0c;m 条边构成的…