POJ 2728 Desert King 01分数规划,最优比率生成树

一个完全图,每两个点之间的cost是海拔差距的绝对值,长度是平面欧式距离,

让你找到一棵生成树,使得树边的的cost的和/距离的和,比例最小

然后就是最优比例生成树,也就是01规划裸题

看这一发:http://blog.csdn.net/sdj222555/article/details/7490797

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<string.h>
using namespace std;
const int N=1e3+5;
const double eps=1e-5;
const int INF=0x3f3f3f3f;
int n;
double x[N],y[N],z[N];
double cost[N][N],dis[N][N];
bool vis[N];
double d[N];
double mst(double x) {
    memset(vis,false,sizeof(vis));
    vis[1]=true;
    for(int i=2; i<=n; ++i) {
        d[i]=cost[1][i]-x*dis[1][i];
    }
    double ret=0;
    for(int i=1;i<n;++i){
      int u;
      double mx=INF;;
      for(int j=2;j<=n;++j)
        if(!vis[j]&&mx>d[j]){
           mx=d[j];
           u=j;
        }
      ret+=mx;
      vis[u]=true;
      for(int j=2;j<=n;++j)
        if(!vis[j]&&d[j]>cost[u][j]-x*dis[u][j])
          d[j]=cost[u][j]-x*dis[u][j];
    }
    return ret;
}
int main() {
    while(~scanf("%d",&n)) {
        if(n==0)break;
        for(int i=1; i<=n; ++i) {
            scanf("%lf%lf%lf",&x[i],&y[i],&z[i]);
            for(int j=1; j<i; ++j) {
                dis[i][j]=dis[j][i]=sqrt(1.0*(x[i]-x[j])*(x[i]-x[j])+1.0*(y[i]-y[j])*(y[i]-y[j]));
                cost[i][j]=cost[j][i]=fabs(z[i]-z[j]);
            }
        }
        double r=200000.0,l=0.0,mid;
        while(r-l>eps) {
            mid=(l+r)/2.0;
            if(mst(mid)>=0)l=mid;
            else r=mid;
        }
        printf("%.3f\n",mid);
    }
    return 0;
}
View Code

 

posted @ 2016-06-02 16:16  shuguangzw  阅读(183)  评论(0编辑  收藏  举报