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

给定整数序列a,b,求出下式的最大值

sum{ai*xi}/sum{bi*xi},xi=0|1

通俗来说,就是选出一些整数对(ai,bi),使得选出的a之和与选出的b之和商最大化

二分答案L,即选出的a之和与b之和的商是L

判断L是否成立,只要判断是否存在sum{ai-L*bi}>0即可

 

poj2728为要找出各边收益除以各边成本的最大生成树

那么二分商L,另边权变成ai-L*bi求最大生成树,如果和>0,答案可行

 

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#define MAXN 1005
#define INF 1000000000
#define eps 1e-7
using namespace std;
int n;
double Edge[MAXN][MAXN],lowcost[MAXN];
int v[MAXN];
struct Point{int x, y, z;}p[MAXN];

double cal(int a, int b)
{
    return sqrt(1.0 * (p[a].x - p[b].x) * (p[a].x - p[b].x) + 1.0 * (p[a].y - p[b].y) * (p[a].y - p[b].y));
}
double prim(double l)//总成本是否可以小于总长度*l ,即cost-l*len>=0,那么cost/len>=l,l得变大 
{
    double cost = 0, len = 0;
    double sum = 0;
    for(int i = 1; i <= n; i++)
    {
        v[i] = 0;
        lowcost[i] = -l*abs(p[1].z - p[i].z) + Edge[1][i];
    }
    v[1] = 1;
    for(int i = 1; i < n; i++)
    {
        double mx = -INF;
        int x = 0;
        for(int j = 1; j <= n; j++)
            if(v[j] != 1 && lowcost[j] > mx){
                x = j;
                mx = lowcost[j];
            }

        v[x] = 1;
        sum += lowcost[x];
        for(int j = 1; j <= n; j++)
        {
            double tmp = -l*abs(p[x].z - p[j].z) + Edge[x][j];
            if(v[j] != 1 && tmp > lowcost[j])
                lowcost[j] = tmp;
        }
    }
    if(sum>=0)return 1;
    return 0;
}
int main()
{
    while(scanf("%d", &n) != EOF && n)
    {
        for(int i = 1; i <= n; i++)
            scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                Edge[i][j] = cal(i, j);
 
        double l = 0.0, r = 100.0, mid,ans;
        while(r - l > 0.0000001)
        {
            mid = (l + r) / 2;
            if(prim(mid)) l = mid,ans=mid;
            else r = mid;
        }
        printf("%.3f\n", 1/ans);
    }
    return 0;
}

 

posted on 2019-03-07 17:17  zsben  阅读(417)  评论(0编辑  收藏  举报

导航