题目 http://poj.org/problem?id=2728

关键词:0/1分数规划,参数搜索,二分法,dinkelbach

参考资料:http://hi.baidu.com/zzningxp/item/28aa46e0fd86bdc2bbf37d03

http://hi.baidu.com/zheng6822/item/b31fbe9d5ae17536336eeb8f

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<math.h>
#define N 1010
#define INF 1e15
#define eps 1e-10
using namespace std;
double X[N],Y[N],Z[N];
double cost[N][N];
double lowcost[N];
int closest[N];int vis[N];
int n;double r;
double disc(int i,int j)
{
return fabs(Z[i]-Z[j]);
}
double disd(int i,int j)
{
return sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]));
}
double prim(double r)
{
double sumc=;double sumd=;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
{
if(i==j)
cost[i][j]=INF;
else
cost[i][j]=disc(i,j)-r*disd(i,j);
}
for(int i=;i<n;i++)
{
lowcost[i]=cost[][i];
vis[i]=;
closest[i]=;
}
closest[]=;
vis[]=;
int k;
for(int i=;i<n;i++)
{
double tmp=INF;
for(int j=;j<n;j++)
if(!vis[j]&&tmp>lowcost[j])
{
k=j;
tmp=lowcost[j];
}
vis[k]=;
for(int j=;j<n;j++)
if(!vis[j]&&lowcost[j]>cost[k][j])
{
lowcost[j]=cost[k][j];
closest[j]=k;
}
}
for(int i=;i<n;i++)
{
sumc+=disc(i,closest[i]);
sumd+=disd(i,closest[i]);
}
return sumc/sumd;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=;i<n;i++)
cin>>X[i]>>Y[i]>>Z[i];
double r1=,r2=;
while()
{
r2=prim(r1);
if(fabs(r1-r2)<=eps)
break;
r1=r2;
}
printf("%.3f\n",r1);
}
return ;
}

PRIM+迭代法

主要算法部分的分析

double prim(double r)
{
/*根据题目要求和算法得到由新的权值组成的图,并且写出邻接矩阵*/
double sumc=0;double sumd=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i==j)
cost[i][j]=INF;
else
cost[i][j]=disc(i,j)-r*disd(i,j);
}
/*初始化*/
for(int i=0;i<n;i++)
{
lowcost[i]=cost[0][i];
vis[i]=0; /*判断该点是否已经在集合内*/
closest[i]=0; /*邻接点*/
}
/*将第一个点加入集合*/
closest[0]=0;
vis[0]=1;
int k;
for(int i=0;i<n;i++)
{
double tmp=INF;
/*通过一次循环找到与第一个点距离最短的点*/
for(int j=0;j<n;j++)
if(!vis[j]&&lowcosat[j]<tmp)
{
k=j;
tmp=lowcost[j];
}
/*将该点加入集合中*/
vis[k]=1;
/*这一步是更新其他的点到集合中的点的距离,closest是用来记录该点的前驱的点的数组,lowcost是用来记录其他点到MST的最短距离的数组,注意是到树上任意一点而不是其中某点*/
for(int j=0;j<n;j++)
if(!vis[j]&&lowcost[j]>cost[j][k])
{
lowcost[j]=cost[j][k];
closest[j]=k;
}
}
/*返回参数,用于迭代*/
for(int i=0;i<n;i++)
{
sumc+=disc(i,closest[i]);
sumd+=disd(i,closest[i]);
}
return sumc/sumd;
}

  

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

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

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

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

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

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

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

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

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

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

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

  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. OA项目_环境搭建

    OA项目现在要做成微服务,用的框架是springboot,所用的编程工具是idea,maven,做为一个程序员最关心的就是我需要在那个架包中编写代码,我们只需关注domain,repository,s ...

  2. 使用 shell 脚本对 Linux 系统和进程资源进行监控

    Shell 简介 Shell 语言对于接触 LINUX 的人来说都比较熟悉,它是系统的用户界面,提供了用户与内核进行交互操作的一种接口.它接收用户输入的命令并把它送入内核去执行.实际上 Shell 是 ...

  3. 分布式ID方案有哪些以及各自的优势

    1.    背景 在分布式系统中,经常需要对大量的数据.消息.http请求等进行唯一标识.例如:在分布式系统之间http请求需要唯一标识,调用链路分析的时候需要使用这个唯一标识.这个时候数据自增主键已 ...

  4. 搭建Mybatis 出现 Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for mapper.BatchCustomer.findBatchCustomerOneToOne

    Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection doe ...

  5. 浅谈JS严格模式

    浅谈JS严格模式 简介 何为严格模式?严格模式(strict mode)即在严格的条件下运行,在严格模式下,很多正常情况下不会报错的问题语句,将会报错并阻止运行. 但是,严格模式可以显著提高代码的健壮 ...

  6. bzoj2733 / P3224 [HNOI2012]永无乡(并查集+线段树合并)

    [HNOI2012]永无乡 每个联通块的点集用动态开点线段树维护 并查集维护图 合并时把线段树也合并就好了. #include<iostream> #include<cstdio&g ...

  7. 嵌入式 Linux 如何操作 GPIO ?

    作者:刘凯链接:https://www.zhihu.com/question/19704852/answer/19760467来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...

  8. 设置VS快捷代码片段

    一.自定义sinppets方式 1.在VS安装路径[D:\vs2013\VC\Snippets\2052\Visual C++]下新建一个snippt文件 2.添加代码 <?xml versio ...

  9. Java多线程,线程交替执行

    两个线程,一个打印1-100的奇数,一个打印1-100的偶数:要求:线程1打印5个之后,线程2开始打印,线程2打印5个之后,线程1再开始打印,以此循环. Code: package com.qhong ...

  10. POJ 3660 Cow ContestCow(Floyd传递闭包)题解

    题意:给出m个关系,问你能确定机头牛的排名 思路:要确定排名那必须要把他和其他n-1头牛比过才行,所以Floyd传递闭包,如果赢的+输的有n-1就能确定排名. 代码: #include<cstd ...