poj2728 Desert King——01分数规划

Posted Zinn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2728 Desert King——01分数规划相关的知识,希望对你有一定的参考价值。

题目:http://poj.org/problem?id=2728

第一道01分数规划题!(其实也蛮简单的)

这题也可以用迭代做(但是不会),这里用了二分;

由于比较裸,不作过多说明了。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define eps 1e-6
using namespace std;
int const inf=0x3f3f3f;
int n;
double d[1005][1005],h[1005][1005],w[1005][1005],dis[1005];
double xx[1005],yy[1005],zz[1005];
bool vis[1005];
void add(int x,int y)
{
    double ds=sqrt((xx[x]-xx[y])*(xx[x]-xx[y])+(yy[x]-yy[y])*(yy[x]-yy[y]));
    d[x][y]=d[y][x]=ds;
    h[x][y]=h[y][x]=fabs(zz[x]-zz[y]);
}
double prim(double mid)
{
    double s=0;
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
            w[i][j]=w[j][i]=h[i][j]-mid*d[i][j];
    for(int i=0;i<n;i++)vis[i]=0,dis[i]=inf;
    dis[0]=0;
    while(1)
    {
        int u=-1;
        for(int i=0;i<n;i++)
            if(!vis[i]&&(u==-1||dis[i]<dis[u]))u=i;
        if(u==-1)break;
        s+=dis[u];vis[u]=1;
        for(int i=0;i<n;i++)
            if(!vis[i])dis[i]=min(dis[i],w[u][i]);
    }
    return s;
}
int main()
{
    while(~scanf("%d",&n))
    {
        if(!n)return 0;
        for(int i=0;i<n;i++)
            scanf("%lf%lf%lf",&xx[i],&yy[i],&zz[i]);
        for(int i=0;i<n;i++)
            for(int j=i+1;j<n;j++)
                add(i,j);
        double l=0,r=100.00;//
        while(r-l>eps)
        {
            double mid=(l+r)/2;
            if(prim(mid)<eps)r=mid;//
            else l=mid;
        }
        printf("%.3lf\n",r);
    }
}

 

以上是关于poj2728 Desert King——01分数规划的主要内容,如果未能解决你的问题,请参考以下文章

01分数规划+prim POJ2728 Desert King

poj2728 Desert King——01分数规划

POJ 2728 Desert King | 01分数规划

$POJ$2728 $Desert King$ 01分数规划

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

poj2728 Desert King(最小生成树+01分数规划=最优比率生成树)