poj2728 最优比率生成树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2728 最优比率生成树相关的知识,希望对你有一定的参考价值。

  这个题的意思是给你一个连通图, 图上每个点都有连个权值ai, bi让你选一个生成树使得sigma(ai*xi)/sigma(bi*xi)最小, 对比与基础的01规划, 我们假设答案是mid, 然后建立一个图, 其新的边的权值是ai-mid*bi, 然后求解最小生成树,假设其答案是tp, 如果tp>=0,说明还有更优的解, 如果小于0那么解小于mid, 代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int inf = 0x3fffffff;
const double eps = 1e-6;
const int maxn = 1000+10;
int n;
struct Vi
{
    int x, y, z;
}vi[maxn];
double ai[maxn][maxn], bi[maxn][maxn];
double ci[maxn][maxn];

double dist(int i, int j)
{
    return sqrt((vi[i].x-vi[j].x)*(vi[i].x-vi[j].x)+(vi[i].y-vi[j].y)*(vi[i].y-vi[j].y));
}
double mincost[maxn];
bool used[maxn];
double check(double mid)
{
    for(int i=0; i<n; i++)
        for(int j=i; j<n; j++)
        {
            ci[i][j] = ai[i][j] - mid*bi[i][j];
            ci[j][i] = ci[i][j];
            if(i==j) ci[i][j] = (double)inf;
        }
    for(int i=0; i<n; i++)
    {
        mincost[i] = (double)inf;
        used[i] = false;
    }
    mincost[0] = 0;
    double res = 0;
    while(true)
    {
        int v = -1;
        for(int u=0; u<n; u++)
            if(!used[u] && (v==-1||mincost[u]<mincost[v])) v=u;
        if(v == -1) break;
        used[v] = true;
        res += mincost[v];
        for(int u=0; u<n; u++)
            mincost[u] = min(mincost[u], ci[v][u]);
    }
    return res;
}

int main()
{
    while(scanf("%d", &n)==1 && n)
    {
        for(int i=0; i<n; i++)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            vi[i] = (Vi){x, y, z};
        }
        double high = 0.0;
        for(int i=0; i<n; i++)
            for(int j=i; j<n; j++)
            {
                ai[i][j] = abs(vi[i].z-vi[j].z);
                ai[j][i] = ai[i][j];
                bi[i][j] = dist(i, j);
                bi[j][i] = bi[i][j];
                high += ai[i][j];
            }
        double l=0.0, r=high+5.0;
        while(r-l >= eps)
        {
            double mid = (l+r)/2.0;
            double tp = check(mid);
            //printf("l=%.3f, r=%.3f, mid=%.3f, tp=%.3f\n", l, r, mid, tp);
            if(tp>=0.0) l=mid;
            else r=mid;
        }
        printf("%.3f\n", l);
    }
    return 0;
}

 

以上是关于poj2728 最优比率生成树的主要内容,如果未能解决你的问题,请参考以下文章

poj2728+最优比率生成树

poj-2728Desert King(最优比率生成树)

[Nowcoder / POJ2728] 最优比率生成树 | 二分 + prim

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

POJ 2728(最优比率生成树+01规划)

[POJ 2728]Desert King(0-1分数规划/最优比率生成树)