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 ...
随机推荐
- XStream的使用方法、简单使用方法、xml的解析方法
下面介绍的是在Android Studio中的使用 Android Studio中目前支持的Xstream最高版本是xstream-1.4.7.jar,大家可以在网上下载,我的是在开源中国项目中有这个 ...
- 设置标题小图标ico
在head里添加 <link rel="shortcut icon" href="<%=request.getContextPath()%>/FlatU ...
- 删除cygwin
由于cygwin 学习了linux 的用户所有者的方式,要删除有一定困难. 所以要右击 然后点 获取管理员所有权 几分钟之后 就可以删了
- Linq skip skipwhile take takewhile
一.Skip()跳过 static void Main(string[] args) { //skip()跳过 ,,,,,,,,,}; //跳过3条 nums.Skip().ToList().ForE ...
- SLF4JLoggerContext cannot be cast to LoggerContext
Getting Exception org.apache.logging.slf4j.SLF4JLoggerContext cannot be cast to org.apache.logging.l ...
- 转 [分享一个SQL] 查会话阻塞关系,层次关系.
with ash as (select /*+ materialize*/* from DBA_HIST_ACTIVE_SESS_HISTORY where sample_time between ...
- 【单源最短路模板】 poj 2387
#include <cstdio> #include <iostream> #include <stdlib.h> #include <memory.h> ...
- EditText的一点深入的了解
最近在开发android下的记事本程序时,频繁的使用EditText控件,折腾来折腾去,算是对其的了解更深入了一些.特将这些收获记录如下: 一.几个属性的介绍 android:gravity=&quo ...
- CodeForces 510B DFS水题
题目大意:在图中找到一个字符可以围成一个环(至少有环四个相同元素) 题目思路:对当前点进行搜索,如果发现可以达到某个已经被查找过的点,且当前点不是由这个点而来,则查找成功. #include<c ...
- 最小点集覆盖/HDU2119
题目连接 先试一下题/?/ 最小点集覆盖=最大匹配 /*根据i.j建图,跑一边最大匹配 */ #include<cstdio> #include<cstring> using ...