POJ2728 Desert King 最优比率生成树
Posted Luowaterbi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2728 Desert King 最优比率生成树相关的知识,希望对你有一定的参考价值。
一开始没理解最优比率生成树为什么要用最小生成树。
书上说的是最大生成树,我一开始觉得是最大生成树,但这样求出来是合法值的最大值,也不是题目上的最小值啊。后来我发现,是在0/1规划二分的意义上理解出错了。
在一般的二分答案中,比如函数是单调递减的,>0的都不是解,<0的都是解,=0的是我们可能要求的解里面的最大值。但是对于0/1规划,二分的是唯一解,>0、<0的都不是解,只有=0的是解。
我们设二分的比率是
k
k
k,树用
x
x
x表示,最小生成树用
x
m
i
n
x_min
xmin表示,最大生成树用
x
m
a
x
x_max
xmax表示,
F
(
k
,
x
)
=
c
o
s
t
(
x
)
−
k
∗
d
i
s
(
x
)
F(k,x)=cost(x)-k*dis(x)
F(k,x)=cost(x)−k∗dis(x)。固定一棵树
x
x
x,
F
(
k
,
x
)
F(k,x)
F(k,x)反比于
k
k
k,
F
(
k
,
x
)
=
0
F(k,x)=0
F(k,x)=0的
k
k
k是正解。
F
(
k
,
x
)
<
0
F(k,x)<0
F(k,x)<0时,说明这棵树的比率比
k
k
k小;
F
(
k
,
x
)
>
0
F(k,x)>0
F(k,x)>0时,说明这棵树的比率比
k
k
k大。
在二分过程中,如果只保证 F ( k , x m a x ) = 0 F(k,x_max)=0 F(k,xmax)=0,那么 F ( k , x m i n ) < F ( k , x m a x ) F(k,x_min)<F(k,x_max) F(k,xmin)<F(k,xmax),即 F ( k , x m i n ) < 0 F(k,x_min)<0 F(k,xmin)<0,那么此时 x m i n x_min xmin的比率显然比 k k k小,因此 k k k需要继续二分。(此时的 k k k实际上为比例最大值。)
AC代码:
#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#include <cstdlib>
#include <stack>
#include <cstring>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define lep(i,a,b) for(int i=(a);i>=(b);i--)
#define lepp(i,a,b) for(int i=(a);i>(b);i--)
#define sci(x) scanf("%d",&(x))
#define scl(x) scanf("%lld",&(x))
#define scs(x) scanf("%s",(x))
#define pri(x) printf("%d\\n",(x))
#define prl(x) printf("%lld\\n",(x))
#define prs(x) printf("%s\\n",(x))
#define pdi pair<double,int>
#define pll pair<long long,long long>
#define mp make_pair
#define All(x) x.begin(),x.end()
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define INFF 0x3f3f3f3f3f3f3f3f
#define multi int T;scanf("%d",&T);while(T--)
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e3+5;
const int mod=1e9+7;
const db eps=1e-6;
const db pi=acos(-1.0);
int n,vis[N];
db z[N][N],w[N][N],v[N][N],dis[N];
struct location
int x,y,z;
c[N];
inline db cal(db a,db b)
return a*a+b*b;
int main()
#ifndef ONLINE_JUDGE
freopen("D:\\\\work\\\\data.in","r",stdin);
#endif
while(cin>>n&&n)
rep(i,1,n)
cin>>c[i].x>>c[i].y>>c[i].z;
rep(j,1,i-1)
z[i][j]=abs(c[i].z-c[j].z);
w[i][j]=sqrt(cal(c[i].x-c[j].x,c[i].y-c[j].y));
db l=0,r=100;
while(r-l>eps)
db mid=(l+r)/2.0;
rep(i,1,n)
dis[i]=1e17;
rep(j,1,i-1) v[i][j]=v[j][i]=z[i][j]-mid*w[i][j];
vis[i]=0;
dis[1]=0;
db tmp=0,mindis=1e17;
int pos;
rep(i,1,n)
mindis=1e17;
rep(j,1,n)
if(vis[j]) continue;
if(dis[j]<mindis)
mindis=dis[j];
pos=j;
tmp+=dis[pos];
vis[pos]=1;
rep(j,1,n)
if(vis[j]==0&&dis[j]>v[pos][j])
dis[j]=v[pos][j];
if(tmp>=0) l=mid;
else r=mid;
cout<<fixed<<setprecision(3)<<l<<endl;
以上是关于POJ2728 Desert King 最优比率生成树的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2728 Desert King(最优比率生成树 01分数规划)