Desert King POJ - 2728(最优比率生成树)

2024-04-11 15:08

本文主要是介绍Desert King POJ - 2728(最优比率生成树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:

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,代表在沙漠中有N个村庄;后面有N组数据,每个数据三个数字X,Y,Z代表村庄在位置(X,Y),且村庄的海拔是Z;

国王想要给每一个村庄供水,没修建一条路的花费是两个村庄之间的海拔之差;

问你想要使每一个村庄的都连接起来,建成的路的平均每公里的花费最小;

思路:

其实这道题是让你求出来  ai / bi  所有和的最小值;

那么假设 ai / bi >=x,那么ai - x*bi >= 0;

这道题可以使用最优比率生成树算法,其中用二分法来枚举  合适的 x 的值;

令F(x)=ai - x*bi,那么这就可以看成一个一元一次的方程式:F(x)=A - x*B,即F(x)=  - B *x + A;

还是看这个图,用二分来枚举f(x) ;

因为是要求最小生成树,所以在每一次的二分判断中要跑一遍prim算法来判断现在的最小生成树的值是否小于0;

如果小于0,那么就是二分区间大了,缩小区间;

如果大于0,那么就是二分区间小了,扩大区间;

代码如下:

#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;const double inf=1e18;
const int maxn=1e3+10;int n;
double cost[maxn][maxn];
double dis[maxn][maxn];
double x[maxn],y[maxn],z[maxn];
int vis[maxn];double get_dis(int a,int b)///计算两点之间的距离;
{return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
}int check(double x)
{memset(vis,0,sizeof vis);double sum=0,lowcost[maxn];vis[1]=1;for(int i=1; i<=n; i++)///计算最小的每一单位距离的花费;lowcost[i]=cost[1][i]-x*dis[1][i];///prim算法;for(int i=2; i<=n; i++)///最小生成树,n-1条边;{double temp=inf;int k=-1;///记录是否还有最小的边;for(int j=2; j<=n; j++){if(!vis[j]&&lowcost[j]<temp){k=j;temp=lowcost[j];}}if(k==-1)break;vis[k]=1;sum+=temp;for(int j=2; j<=n; j++)///松弛;{if(!vis[j]&&cost[k][j]-x*dis[k][j]<lowcost[j])lowcost[j]=cost[k][j]-x*dis[k][j];}}if(sum>=0)return 1;elsereturn 0;
}int main()
{while(~scanf("%d",&n)&&n){for(int i=1; i<=n; i++){scanf("%lf%lf%lf",&x[i],&y[i],&z[i]);}for(int i=1; i<=n; i++)///存储图的数据;{for(int j=i+1; j<=n; j++){dis[i][j]=dis[j][i]=get_dis(i,j);cost[i][j]=cost[j][i]=fabs(z[i]-z[j]);}}///二分枚举;double l=0.0,r=100.0;while(r-l>=1e-5){double mid=(l+r)/2;if(check(mid))l=mid;///扩大区间;elser=mid;///缩小区间;}printf("%.3f\n",l);///注意输出格式;}return 0;
}

 

这篇关于Desert King POJ - 2728(最优比率生成树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/894417

相关文章

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅

Python使用python-pptx自动化操作和生成PPT

《Python使用python-pptx自动化操作和生成PPT》这篇文章主要为大家详细介绍了如何使用python-pptx库实现PPT自动化,并提供实用的代码示例和应用场景,感兴趣的小伙伴可以跟随小编... 目录使用python-pptx操作PPT文档安装python-pptx基础概念创建新的PPT文档查看

在ASP.NET项目中如何使用C#生成二维码

《在ASP.NET项目中如何使用C#生成二维码》二维码(QRCode)已广泛应用于网址分享,支付链接等场景,本文将以ASP.NET为示例,演示如何实现输入文本/URL,生成二维码,在线显示与下载的完整... 目录创建前端页面(Index.cshtml)后端二维码生成逻辑(Index.cshtml.cs)总结

Python实现数据可视化图表生成(适合新手入门)

《Python实现数据可视化图表生成(适合新手入门)》在数据科学和数据分析的新时代,高效、直观的数据可视化工具显得尤为重要,下面:本文主要介绍Python实现数据可视化图表生成的相关资料,文中通过... 目录前言为什么需要数据可视化准备工作基本图表绘制折线图柱状图散点图使用Seaborn创建高级图表箱线图热

SQLServer中生成雪花ID(Snowflake ID)的实现方法

《SQLServer中生成雪花ID(SnowflakeID)的实现方法》:本文主要介绍在SQLServer中生成雪花ID(SnowflakeID)的实现方法,文中通过示例代码介绍的非常详细,... 目录前言认识雪花ID雪花ID的核心特点雪花ID的结构(64位)雪花ID的优势雪花ID的局限性雪花ID的应用场景

Django HTTPResponse响应体中返回openpyxl生成的文件过程

《DjangoHTTPResponse响应体中返回openpyxl生成的文件过程》Django返回文件流时需通过Content-Disposition头指定编码后的文件名,使用openpyxl的sa... 目录Django返回文件流时使用指定文件名Django HTTPResponse响应体中返回openp

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs