POJ 2728 Desert King 最优比率生成树
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 20978 | Accepted: 5898 |
【Description】
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】
【Output】
【Sample Input】
4
0 0 0
0 1 1
1 1 2
1 0 3
0
【Sample Output】
1.000
【题意】
给出一张完全图,每条边都有长度和花费,要求在图中找到一棵生成树,使得Sum(Cost)/Sum(dist)达到最小。
【分析】
据说05年ACM的某场比赛上,教主怒切一题最优比率生成树,坑死了无数跟榜着...-_-////
最优比率生成树的前导知识是01分数规划。
基本思路是Dinkelbach逼近法:
整体思路跟原本的01分数规划基本相同,方程F(L)=Sum(cost[i])/Sum(dist[i]),只要把L'的生成过程改成Prim即可。
Prim堆加边的时候,用cost-l*dist作为边权。
/* ***********************************************
MYID : Chen Fan
LANG : G++
PROG : PKU_2728
************************************************ */ #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <bitset> using namespace std; typedef struct nod
{
int x,y,z;
} node;
node p[]; double getdist(int i,int j)
{
return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
} typedef struct enod
{
int x,y;
double dist,cost,r;
friend bool operator < (enod a,enod b)
{
return a.r>b.r;
}
} enode; enode gete(int x,int y,double dist,double cost,double l)
{
enode a;
a.x=x;a.y=y;a.dist=dist;a.cost=cost;
a.r=cost-l*dist;
return a;
} double prim(int n,double l)
{
priority_queue<enode> q;
while (!q.empty()) q.pop();
bitset<> flag;
flag.reset();
flag[]=;
double cost=,dist=;
for (int i=;i<=n;i++) q.push(gete(,i,getdist(,i),abs(p[].z-p[i].z),l)); for (int i=;i<n;i++)
{
enode now=q.top();
q.pop();
while (flag[now.y])
{
now=q.top();
q.pop();
}
flag[now.y]=;
cost+=now.cost;dist+=now.dist;
for (int j=;j<=n;j++)
if (j!=now.y&&!flag[j])
q.push(gete(now.y,j,getdist(now.y,j),abs(p[now.y].z-p[j].z),l));
} return cost/dist;
} int main()
{
freopen("2728.txt","r",stdin); int n;
while (scanf("%d",&n))
{
if (n==) break; for (int i=;i<=n;i++) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z); double l=,ans;
while ()
{
ans=prim(n,l);
if (fabs(ans-l)<1e-) break;
else l=ans;
} printf("%.3f\n",ans);
} return ;
}
POJ 2728 Desert King 最优比率生成树的更多相关文章
- POJ.2728.Desert King(最优比率生成树 Prim 01分数规划 二分/Dinkelbach迭代)
题目链接 \(Description\) 将n个村庄连成一棵树,村之间的距离为两村的欧几里得距离,村之间的花费为海拔z的差,求花费和与长度和的最小比值 \(Solution\) 二分,假设mid为可行 ...
- POJ 2728 Desert King(最优比率生成树, 01分数规划)
题意: 给定n个村子的坐标(x,y)和高度z, 求出修n-1条路连通所有村子, 并且让 修路花费/修路长度 最少的值 两个村子修一条路, 修路花费 = abs(高度差), 修路长度 = 欧氏距离 分析 ...
- POJ 2728 Desert King (最优比率树)
题意:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差,现在要求方案使得费用与距离的比值最小,很显然,这个题目 ...
- POJ 2728 Desert King (最优比例生成树)
POJ2728 无向图中对每条边i 有两个权值wi 和vi 求一个生成树使得 (w1+w2+...wn-1)/(v1+v2+...+vn-1)最小. 采用二分答案mid的思想. 将边的权值改为 wi- ...
- POJ2728 Desert King —— 最优比率生成树 二分法
题目链接:http://poj.org/problem?id=2728 Desert King Time Limit: 3000MS Memory Limit: 65536K Total Subm ...
- Desert King(最优比率生成树)
Desert King Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 22717 Accepted: 6374 Desc ...
- 【POJ2728】Desert King 最优比率生成树
题目大意:给定一个 N 个点的无向完全图,边有两个不同性质的边权,求该无向图的一棵最优比例生成树,使得性质为 A 的边权和比性质为 B 的边权和最小. 题解:要求的答案可以看成是 0-1 分数规划问题 ...
- POJ2728 Desert King 最优比率生成树
题目 http://poj.org/problem?id=2728 关键词:0/1分数规划,参数搜索,二分法,dinkelbach 参考资料:http://hi.baidu.com/zzningxp/ ...
- poj 2728 Desert King (最优比率生成树)
Desert King http://poj.org/problem?id=2728 Time Limit: 3000MS Memory Limit: 65536K Descripti ...
随机推荐
- iOS开发 GET、POST请求方法:NSURLSession篇
NSURLConnection,在iOS 9被宣布弃用,本文不使用NSURLConnection进行网络编程,有兴趣的童鞋可以参考: iOS开发 GET.POST请求方法(NSURLConnectio ...
- C# tostring()汇总
原文:http://www.cnblogs.com/xiaopin/archive/2010/11/05/1870103.html C 货币 2.5.ToString("C") ¥ ...
- Ztree当节点没有下级时不显示下拉图标
select o.*,(select count(*) from sys_org t where t.orgsupid=o.orgid) isLeaf from sys_org o where 1=1
- Android图片处理神器BitmapFun源码分析
作为一名Android开发人员,相信大家对图片OOM的问题已经耳熟能详了,关于图片缓存和解决OOM的开源项目也是相当的多,被大家熟知的就是Universal_image_loader和Volley了, ...
- sql 指定范围 获取随机数
DECLARE @nMinimumCount INT= 1DECLARE @nMaximumCount INT= 100SELECT abs(CHECKSUM(NEWID()))%(@nMaximum ...
- UVA - 437 The Tower of Babylon(dp-最长递增子序列)
每一个长方形都有六种放置形态,其实可以是三种,但是判断有点麻烦直接用六种了,然后按照底面积给这些形态排序,排序后就完全变成了LIS的问题.代码如下: #include<iostream> ...
- Map 根据value 排序
总是有特殊的需求 ,呵呵 ,一起看看Map 根据value 排序的一个例子吧,还用到了泛型 很不错 此文仅供自己记录笔记. /** * hashmap 根据值排序 */ public static & ...
- thinkPHP17---操作绑定到类
首先要配置: "ACTION_BIND_CLASS"=>"TRUE"; 控制器类的定义如下: namespace Home\Controller\Inde ...
- Oracle sql优化之分析函数优化标量子查询
待优化语句如下 select a.code as code, a.m_code as m_code,a.stktype as f_stype,a.e_year as e_year, b.sname a ...
- HDU 4685 Prince and Princess
强连通分量,看大神的题解才会写的.... http://www.cnblogs.com/kuangbin/p/3261157.html 数据量有点大,第一次Submit 2995ms过的,时限3000 ...