POJ 2718 分数规划

链接:

http://poj.org/problem?id=2728

题意:

给你n个点,每两个点之间有value和cost,找一个最小生成树,使得∑cost/∑value最小

题解:

典型的分数规划题,二分+最小生成树就可以了

代码:

31 struct point { double x, y, z; }p[MAXN];
32 double a[MAXN][MAXN];
33 double b[MAXN][MAXN];
34 double cost[MAXN][MAXN];
35 double d[MAXN];
36 bool used[MAXN];
37 int n;
38 
39 double prim() {
40     rep(i, 0, n) d[i] = 1e20;
41     memset(used, 0, sizeof(used));
42     d[0] = 0;
43     double res = 0;
44 
45     while (1) {
46         int v = -1;
47         rep(u, 0, n) if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
48         if (v == -1) break; used[v] = 1; res += d[v];
49         rep(u, 0, n) d[u] = min(d[u], cost[v][u]);
50     }
51     return res;
52 }
53 
54 double sqr(double x) {
55     return x*x;
56 }
57 
58 bool check(double x) {
59     rep(i, 0, n) rep(j, 0, n)
60         cost[i][j] = -x * a[i][j] + b[i][j];
61     return prim() >= 0;
62 }
63 
64 int main() {
65     ios::sync_with_stdio(false), cin.tie(0);
66     while (cin >> n, n) {
67         rep(i, 0, n) cin >> p[i].x >> p[i].y >> p[i].z;
68         rep(i, 0, n) rep(j, 0, n) {
69             a[i][j] = sqrt(sqr(p[i].x - p[j].x) + sqr(p[i].y - p[j].y));
70             b[i][j] = fabs(p[i].z - p[j].z);
71         }
72         double l = 0, r = 100;
73         rep(i, 0, 20) {
74             double m = (l + r) / 2;
75             if (check(m)) l = m;
76             else r = m;
77         }
78         printf("%.3f\n", l);
79     }
80     return 0;
81 }
posted @ 2017-05-03 22:49  Flowersea  阅读(249)  评论(0编辑  收藏  举报