• POJ 2728 Desert King


    最优比率生成树

    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
    ", mid);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Java中的变量
    Java是什么
    leetcode 75. 颜色分类
    leetcode 283. 移动零
    剑指 Offer 65. 不用加减乘除做加法
    剑指 Offer 53
    剑指 Offer 58
    剑指 Offer 58
    剑指 Offer 57
    剑指 Offer 57. 和为s的两个数字
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8669934.html
Copyright © 2020-2023  润新知