• POJ2728 Desert King 题解 最优比率生成树 01分数规划


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

    题目大意:

    给你一个无向图,每条边有一个价值和长度,求一棵生成树,其对应的价值和与长度和的币值最小。

    解题思路:
    01分数规划。对每一个 (mid),以 (a_i - mid imes b_i) 为边求最小生成树,判断最小生成树的长度是否 (ge 0)

    示例代码:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    const int maxn = 1010;
    int n, x[maxn], y[maxn], z[maxn];
    double dis[maxn][maxn], cost[maxn];
    bool vis[maxn];
    bool prim(double mid) {
        memset(vis, 0, sizeof(bool)*n);
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < i; j ++) {
                dis[i][j] = dis[j][i] = abs(z[i] - z[j]) - mid * sqrt((x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]));
            }
        }
        cost[0] = 0;
        for (int i = 1; i < n; i ++) cost[i] = 1e9;
        double ans = 0;
        for (int j = 0; j < n; j ++) {
            int u = -1;
            for (int i = 0; i < n; i ++) if (!vis[i] && (u == -1 || cost[u] > cost[i])) u = i;
            if (u == -1) break;
            ans += cost[u];
            vis[u] = true;
            for (int i = 0; i < n; i ++) if (!vis[i] && dis[u][i] < cost[i]) cost[i] = dis[u][i];
        }
        return ans >= 0;
    }
    int main() {
        while (~scanf("%d", &n) && n) {
            for (int i = 0; i < n; i ++) scanf("%d%d%d", x+i, y+i, z+i);
            double L = 0, R = 100.0;
            while (R - L > 1e-4) {
                double mid = (L + R) / 2;
                if (prim(mid)) L = mid;
                else R = mid;
            }
            printf("%.3f
    ", L);
        }
        return 0;
    }
    
  • 相关阅读:
    学习hadoop
    贵在坚持
    保护好自己的毕业论文
    博客园与CSDN的选择
    Matlab中的“prod”函数
    js实现HashMap()
    js常用正则表达式
    苹果手机使用替代onkeyup的方法
    keydown
    ArrayAndString(数组和字符串)
  • 原文地址:https://www.cnblogs.com/quanjun/p/13992034.html
Copyright © 2020-2023  润新知