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 ...
随机推荐
- 推翻自己和过往,重学自定义View
http://blog.csdn.net/lfdfhl/article/details/51671038 深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 A ...
- 转: Windows下安装Oracle Database 12c Release 1(12.1.0.2.0) - Enterprise Edition
http://www.cnblogs.com/xqzt/p/4395053.html Windows下安装Oracle Database 12c Release 1(12.1.0.2.0) - Ent ...
- 【转】VC6.0打开或者添加工程文件崩溃的解决方法
很多学习编程的同学都遇到这样的问题,在Windows操作系统下使用Visual C++ 6.0编程时,如果点击菜单中的[打开]或者[添加],或者按快捷键,都会弹出下图的对话框,出现程序崩溃并退出的情况 ...
- 最小点集覆盖=最大匹配<二分图>/证明
来源 最小点集覆盖==最大匹配. 首先,最小点集覆盖一定>=最大匹配,因为假设最大匹配为n,那么我们就得到了n条互不相邻的边,光覆盖这些边就要用到n个点. 现在我们来思考为什么最小点击覆盖一定& ...
- Top 100 Best Blogs for iOS Developers
(by JP Zhang | Last updated: Apr 5, 2016 ) 转载自:http://www.softwarehow.com/best-blogs-for-ios-develo ...
- 给Notepad++ 加带图标右键菜单
给Notepad++ 加带图标右键菜单 方式一: 拷贝以下代码建立一个reg文件,替换相关路径,保存,双击运行加入注册表 Windows Registry Editor Version 5.00 [H ...
- Android中获取网络数据时的分页加载
//此实在Fragment中实现的,黄色部分为自动加载,红色部分是需要注意的和手动加载, 蓝色部分是睡眠时间,自我感觉不用写 ,还有就是手动加载时,不知道为什么进去后显示的就是最后一行,求大神 ...
- acm课程练习2--1002
题目描述 Now, here is a fuction: F(x) = 6 * x^7+8x^6+7x^3+5x^2-yx (0 <= x <=100)Can you find the ...
- 什么是Jsp
1.什么是jsp java server page(java 服务器端页面技术),是 sun 公司制订的一种服务器端动态页面生成技术的规范. 因为直接使用 servlet 生成页面,如果页面比较复杂, ...
- hosts文件不显示
1.按住windows键(就是小旗子小窗口键)+R,打开运行:2.在输入框中输入 cmd并回车:3.紧接着在dos窗口中输入"CD \WINDOWS\SYSTEM32\DRIVERS\ETC ...