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

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
题解:先是超时,然后wa,最小生成树生疏了。。。
这个就是01分数规划的变形,即找到K求hi-li*K的最小生成树使得k最小;

有N个村庄,给出每个村庄的坐标和海拔,,benifit为两点之间的距离,cost为两点的高度差,现在要求一棵树使得 cost / benift 最小,即求一个最优比例生成树

第一次遇见这种生成树,在网上找了个解法

假设sigma(h)/sigma(l)==K 均值K可取,即: sigma(h)==K*sigma(l)

sigma(h)==K*(l1+l2+l3+...lm)

sigma(h)==K*l1+K*l2+K*l3+...K*lm

把原来的每个边的h都减去K*l

即hi'=hi-li'==hi-li*K

然后问题可以转换到求hi'这些边的最小生成树了

如果hi'这些边得最小生成树权值和<=0.0,说明K这个均值可取

对于k,二分求解即可

代码:

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define mem(x,y) memset(x,y,sizeof(x))
using namespace std;
const int INF=0x3f3f3f3f;
typedef long long LL;
const int MAXN=;
double vis[MAXN],low[MAXN];
int N;
double R;
struct Node{
double x,y,h;
};
Node dt[MAXN];
double len[MAXN][MAXN],cost[MAXN][MAXN];
double getl(Node a,Node b){
double x=b.x-a.x,y=b.y-a.y;
return sqrt(x*x+y*y);
} bool prime(){
double total;
mem(vis,);
for(int i=;i<N;i++)low[i]=cost[][i]-R*len[][i];
total=;
vis[]=;//0没有被标记为1。。。错了半天;
for(int i=;i<N;i++){
double temp=INF;
int k;
for(int j=;j<N;j++)
if(!vis[j]&&low[j]<temp)temp=low[j],k=j;
if(temp==INF)break;
total+=temp;
vis[k]=;
for(int j=;j<N;j++)
if(!vis[j]&&low[j]>cost[k][j]-R*len[k][j])low[j]=cost[k][j]-R*len[k][j];
}
//printf("total=%lf R=%lf\n",total,R);
if(total>)return true;
else return false;
}
int main(){
while(scanf("%d",&N),N){
mem(len,INF);
mem(cost,INF);
double mxl=-INF,mil=INF,mxc=-INF,mic=INF;
for(int i=;i<N;i++)
scanf("%lf%lf%lf",&dt[i].x,&dt[i].y,&dt[i].h); for(int i=;i<N;i++){
for(int j=i+;j<N;j++){
len[j][i]=len[i][j]=getl(dt[i],dt[j]);
cost[j][i]=cost[i][j]=abs(dt[i].h-dt[j].h);
mxl=max(mxl,len[i][j]);
mxc=max(mxc,cost[i][j]);
mil=min(mil,len[i][j]);
mic=min(mic,cost[i][j]);
}
}
//printf("%lf %lf %lf %lf\n",mil,mic,mxl,mxc);
double l=mic/mxl,r=mxc/mil;//要是从0到mx会超时; // printf("%lf %lf\n",l,r);
while(r-l>1e-){
R=(l+r)/;
if(prime())l=R;
else r=R;
}
printf("%.3f\n",l);
}
return ;
}

Desert King(最优比率生成树)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. C++/C#结构体转化-二维数组-bytes To Strings

    C++结构体 typedef struct VidyoClientRequestGetWindowsAndDesktops_ { /*! The number of application windo ...

  2. vsvim _vsvimrc 设置(转)

    c_joewang的专栏 (转) vsvim安装到vs2010后可以使用绝大部分原生vim的编辑功能,包括宏录制,也可以通过配置设置键盘映射,关于支持的编辑功能等可以参考上面链接去查看相关文档. Vi ...

  3. ExtJS4.2学习(二)——入门基础

    1.工程的目录结构: src里放后台的文件,WebRoot里放前台的文件. index.html或者index.jsp等是整个项目的首页,在首页我们要引入ExtJS的CSS样式文件和ExtJS的核心类 ...

  4. css样式写一个三角形

    <style> .test{ border-color:transparent #abcdef transparent transparent; border-style:solid; b ...

  5. 决策树ID3算法[分类算法]

    ID3分类算法的编码实现 <?php /* *决策树ID3算法(分类算法的实现) */ /* *求信息增益Grain(S1,S2) */ //-------------------------- ...

  6. java Socket 列子 一些参数设置比较全

    http://blog.csdn.net/a19881029/article/details/11596945

  7. 四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法

    四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法  原创文章,欢迎转载,转载请注明出处      最近时间花在最多的地方就是STM32的I2C上了.之前就知道STM32的I2C并不好用, ...

  8. 数字运算、ASCII

    num20 = dollar/20;num10 = (dollar - 20*num20)/10;num5 =(dollar-20*num20-10*num10)/5;//可以写为num5 = (do ...

  9. 射频识别技术漫谈(29)——射频接口芯片TRF7960

    TRF7960系列是TI推出的载波为13.56MHz.支持ISO15693.ISO14443A/B和FeliCa协议的射频接口芯片.许多人更关心它能不能读写MF1卡片,就我的理解及实际验证,由于MF1 ...

  10. 2015 11 27编写JAVA程序

    在任意文件下 ,建立一个文本文档,更改其txt格式为java格式, 打开此程序的同时打开eclipse可编写代码. public class 文件名{ public static void main( ...