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 ...
随机推荐
- sqldeveloper连接mysql
sqldeveloper连接mysql 腑镜诏 钌d 汁叁ㄧ勋 佚蔡弥噙 不仅仅是越南帮和戴爷的事情还有谢婉莹的条 炔验遒其 倒扇油┣ 砹笄谤 几句话孟飞的信心大增兴奋不已换句话说 谠诂k厝 ...
- Qt 5入门指南之Qt Quick编程示例
编程示例 使用Qt创建应用程序是十分简单的.考虑到你的使用习惯,我们编写了两套教程来实现两个相似的应用程序,但是使用了 不同的方法.在开始之前,请确保你已经下载了QtSDK的商业版本或者开源版本,并且 ...
- windows的DOS窗口如何修改大小
关于这个问题,其实很简单.不知道为什么网上的资料乱遭的.故自己写下来,方便有不明白的童鞋参考. 左键点击左上角的区域会弹出一个菜单,选择属性. 如下图就能轻松的修改窗口的大小了.
- perl的USE和require
来源: http://www.cnblogs.com/itech/archive/2010/11/22/1884345.html 相同: 都可以用来引用module(.PM). 不同: 1) 区别在于 ...
- Java多态(一)
父类: public class Parent { public String name; private String pass; public void say1(AA aa){ System.o ...
- mvc动态生成a标签,多个属性,多个querystring
1*服务端 客户端 跳转的url 2*服务端 客户端 跳转的url 3*服务端 客户端 跳转的url 4*服务端 客户端 跳转的url
- 给postgresql 创建新的用户
\du 查看当前postgresql的用户,一般此时只能看到 postgres create user ysr superuser password '123456'; \du 就可以看到两个用户了. ...
- iOS客户端开发与Web前端开发
转载自:http://blog.cnbang.net/tech/1813/不知不觉做iOS客户端开发已经半年多了,了解到iOS客户端开发与Web前端开发的一些异同,写一下. 版本升级.用户角度上看,客 ...
- 直接在script里面换样式IE6,7,8不兼容
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- 2016湖南省赛--A题--2016
2016 [TOC] Description 给出正整数 n 和 m,统计满足以下条件的正整数对 (a,b) 的数量: 1. 1≤a≤n,1≤b≤m; 2. a×b 是 2016 的倍数. Input ...