码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2728 Desert King

时间:2018-03-29 16:07:22      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:mst   mem   get   else   body   cal   eps   注意   +=   

最优比率生成树

01 分数规划与MST的结合,注意总成本与总长度比值最小,不等价于总长度与总成本比值最大

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define eps 1e-6
using namespace std;
const int MAXN = 1005;
int init() {
    int rv = 0, fh = 1;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') fh = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        rv = (rv<<1) + (rv<<3) + c - '0';
        c = getchar();
    }
    return fh * rv;
}
int n, x[MAXN], y[MAXN], hei[MAXN];
double val[MAXN][MAXN], cot[MAXN][MAXN], fin[MAXN][MAXN], l, r, mid, dis[MAXN];
bool f[MAXN];
double cal(int a, int b) {
    return sqrt((double)(x[a] - x[b]) * (x[a] - x[b]) + (y[a] - y[b]) * (y[a] - y[b]));
}
bool chk(double x) {
    memset(f, 0, sizeof(f));
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            fin[i][j] = cot[i][j] - x * val[i][j] ;
            //if(x == 1.0) printf("%f ", fin[i][j]);
        }
    }
    double ans = 0.0;
    f[1] = 1;
    for(int i = 1; i <= n; i++) {
        dis[i] = fin[1][i];
    }
    for(int i = 1; i < n; i++) {
        int k = 0;
        double mi = 1e10;
        for(int j = 1; j <= n; j++) {
            if(!f[j]) {
                if(mi > dis[j]) mi = dis[j], k = j;
            }
        }
        if(!k) break;
        f[k] = 1;
        ans += dis[k];
        for(int j = 1; j <= n; j++ ){
            if(!f[j]) {
                if(dis[j] > fin[k][j]) dis[j] = fin[k][j];
            }
        }
    }
    return (ans >= 0.0);
}
int main() {
    while(1) {
        n = init();
        if(!n) break;
        for(int i = 1; i <= n; i++) x[i] = init(), y[i] = init(), hei[i] = init();
        l = r = mid = 0.0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                val[i][j] = cal(i, j);
                r += val[i][j];
                cot[i][j] = (double) abs(hei[i] - hei[j]);
            }
        }
        r = 100.0;
        while(r - l > eps) {
            mid = (l + r) * 0.5;
            if(chk(mid)) {
                l = mid;
            }else r = mid;
        }
        printf("%.3f\n", mid);
    }
    return 0;
}

POJ 2728 Desert King

标签:mst   mem   get   else   body   cal   eps   注意   +=   

原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8669934.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!