题目大意:

有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,

只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差,

现在要求方案使得费用与距离的比值最小,很显然,这个题目是要求一棵最优比率生成树。

————————————————————————————————————

这是一道最优比率生成树的题目,是个很明显的0-1分数规划,设每条边代价为ci,距离为di

那么题目要求(∑(ci*xi))/(∑(di*xi))的最小值 xi∈{0,1}

我们进行一波转换

z=(∑(ci*xi))-r'*(∑(di*xi)),其中z是左边这个式子的最小值

由于di为正数,xi为非负数,所以

r'>r 时 z(r')<0

r'=r 时 z(r')=0

r'<r 时 z(r')>0

那么二分这个最小值,将这个式子化成xi(ci-r'*di)的形式,每条边的权值变成ci-r'*di

对于这些边,求一棵最小生成树,MST的值即为z(r')

这样问题就解决了QAQ(注:! 这里输出要%.3f 不能lf !!! 我错了五次就在这里

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int M=1e4+;
const double inf=1e15;
int n;
int v[M][M];
int x[M],y[M],w[M],vis[M];
double d[M],map[M][M];
double calc(int s1,int s2){return sqrt(1.0*(x[s1]-x[s2])*(x[s1]-x[s2])+1.0*(y[s1]-y[s2])*(y[s1]-y[s2]));}
double prim(double k){
double sum=;
memset(vis,,sizeof(vis));
d[]=; vis[]=;
for(int i=;i<=n;i++) d[i]=(double)v[][i]-k*map[][i];
for(int i=;i<=n;i++){
double mn=inf;
int h=;
for(int j=;j<=n;j++) if(!vis[j]&&mn>d[j]) mn=d[j],h=j;
sum+=mn; d[h]=; vis[h]=;
for(int j=;j<=n;j++) if(!vis[j]&&((double)v[h][j]-k*map[h][j])<d[j]) d[j]=(double)v[h][j]-k*map[h][j];
}
return sum;
}
int main()
{
while((scanf("%d",&n)!=EOF)&&n){
for(int i=;i<=n;i++) scanf("%d %d %d",&x[i],&y[i],&w[i]);
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++) map[i][j]=map[j][i]=calc(i,j),v[i][j]=v[j][i]=abs(w[i]-w[j]);
double l=0.0,r=100000.0;
while(r-l>1e-){
double mid=(l+r)/;
if(prim(mid)>=) l=mid;
else r=mid;
}printf("%.3f\n",r);
}
return ;
}

poj2728 最小比率生成树——01分数规划的更多相关文章

  1. POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)

    用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一 ...

  2. POJ 2728 Desert King(最优比率生成树 01分数规划)

    http://poj.org/problem?id=2728 题意: 在这么一个图中求一棵生成树,这棵树的单位长度的花费最小是多少? 思路: 最优比率生成树,也就是01分数规划,二分答案即可,题目很简 ...

  3. Desert King (poj 2728 最优比率生成树 0-1分数规划)

    Language: Default Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 22113   A ...

  4. 【题解】 [HNOI2009] 最小圈 (01分数规划,二分答案,负环)

    题目背景 如果你能提供题面或者题意简述,请直接在讨论区发帖,感谢你的贡献. 题目描述 对于一张有向图,要你求图中最小圈的平均值最小是多少,即若一个圈经过k个节点,那么一个圈的平均值为圈上k条边权的和除 ...

  5. zoj 2676 二分+ISAP模板求实型参数的最小割(0-1分数规划问题)(可做ISAP模板)

    /* 参考博文:http://www.cnblogs.com/ylfdrib/archive/2010/09/01/1814478.html 以下题解为转载代码自己写的: zoj2676 胡伯涛论文& ...

  6. BZOJ1486 HNOI2009 最小圈 【01分数规划】

    BZOJ1486 HNOI2009 最小圈 Description 应该算是01分数规划的裸板题了吧..但是第一次写还是遇到了一些困难,vis数组不清零之类的 假设一个答案成立,那么一定可以找到一个环 ...

  7. 2018.09.24 bzoj1486: [HNOI2009]最小圈(01分数规划+spfa判负环)

    传送门 答案只保留了6位小数WA了两次233. 这就是一个简单的01分数规划. 直接二分答案,根据图中有没有负环存在进行调整. 注意二分边界. 另外dfs版spfa判负环真心快很多. 代码: #inc ...

  8. poj2728 生成树01分数规划 (二分答案)

    给定整数序列a,b,求出下式的最大值 sum{ai*xi}/sum{bi*xi},xi=0|1 通俗来说,就是选出一些整数对(ai,bi),使得选出的a之和与选出的b之和商最大化 二分答案L,即选出的 ...

  9. 【POJ2728】Desert King - 01分数规划

    Description David the Great has just become the king of a desert country. To win the respect of his ...

随机推荐

  1. LInux操作随手笔记

    一.find 的用法 实例 find / -name test.txt 就可以找到这个文件的路径(如果存在). 二.学用vi编辑器,学用rz往linux服务器上面上传文件 linux中rz 和 sz ...

  2. 输入cin对象的用法

    #include<iostream> using namespace std; int main() { int carrots ; cout << "How man ...

  3. [Bzoj3252]攻略(dfs序+线段树)

    Description 题目链接 Solution 可以想到,每次肯定是拿最大价值为最优 考虑改变树上一个点的值,只会影响它的子树,也就是dfs序上的一个区间, 于是可以以dfs序建线段树,这样就变成 ...

  4. ABAP CDS - SELECT, association

    ABAP CDS - SELECT, association Syntax ... ASSOCIATION [ [min..max] ] TO target [AS _assoc] ON cond_e ...

  5. 20145202马超GDB调试汇编堆栈过程分析

    20145202马超GDB调试汇编堆栈过程分析 esc :w保存,:wq保存并退出 x:删除错误的单个字母 dw:删除整个单词 gcc hello.c -o hello:运行hello.c gcc - ...

  6. Spring---资源访问工具类

    JDK所提供的访问资源的类并不能很好的满足各种底层资源的访问需求,因此,Spring设计了一个Resource接口,它为应用提供了更强大的访问底层资源的能力 主要方法 boolean exists() ...

  7. 一步一步学Linq to sql(一):预备知识

    什么是Linq to sql Linq to sql(或者叫DLINQ)是LINQ(.NET语言集成查询)的一部分,全称基于关系数据的 .NET 语言集成查询,用于以对象形式管理关系数据,并提供了丰富 ...

  8. android MotionEvent

    getAction() 获取事件的类型,这是一个组合值,由pointer的index值和事件类型值组合而成的 getActionMasked() 获取事件的类型,不具有其他信息 参考: http:// ...

  9. 手把手教你如何逐步安装OpenStack

    [TechTarget中国原创] 尽管OpenStack官方提供的在线安装教程和分步向导能够为管理员提供很大帮助,但是依然存在很多不尽如人意的地方.因此在Ubuntu上安装OpenStack的过程当中 ...

  10. 一个python的文件对比脚本

    脚本主要用来给游戏客户端做热更的. 处理方式就是针对每个文件求其MD5值,再根据文件的目录和名字对比两个版本的MD5值,如果不一样,则这次热更就需要更新这个文件. 用法很简单. 1,生成MD5码列表 ...