LouZhang

导航

poj_2728,最优比率生成树

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

上次也做过类似的,就是花费和路径的比值最小,不过和这不一样。。。。

证明就网上搜吧。。一大堆。。

我这是看别人的代码写的,迭代。。。

错在精度上搞好久了。。。

#include<cstdio>
#include<cstring>
#include<cmath>

const int maxn(1010);
#define inf 999999999
int n;
double g[maxn][maxn], cost[maxn][maxn];
int vis[maxn];
double dist[maxn];
double x[maxn], y[maxn], z[maxn];
int pre[maxn];
double prim(double a){
    double totalcost = 0.0, totaldist = 0.0;
    for(int i = 1; i <= n; i ++) pre[i] = 1;
    dist[1] = 0;
    memset(vis, 0, sizeof vis);
    vis[1] = 1;
    for(int i = 2; i <= n; i ++)
      dist[i] = cost[1][i] - g[1][i]*a;
    for(int i = 2; i <= n; i ++){
        int u;
        double min = inf*1.0;
        for(int j = 2; j <= n; j ++){
            if(!vis[j] && dist[j] < min){
                min = dist[j];
                u = j;
            }
        }
        vis[u] = 1;
        totalcost += cost[pre[u]][u];
        totaldist += g[pre[u]][u];
        for(int j = 1; j <= n; j ++){
            if(!vis[j] && dist[j] > cost[u][j] - g[u][j]*a){
                dist[j] = cost[u][j] - g[u][j]*a;
                pre[j] = u;
                //printf("%d\n", u);
            }
        }
    }
    return totalcost/totaldist;
}
int main(){
    while(scanf("%d", &n), n){
        for(int i = 1; i <= n; i ++){
            scanf("%lf%lf%lf", x+i, y+i, z+i);
            for(int j = 1; j < i; j ++){
                double tmp = (x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]);
                cost[i][j] = cost[j][i] = fabs(z[i] - z[j]);
                g[i][j] = g[j][i] = sqrt(tmp);
            }
        }
        double a = 0;
        while(true){
            double b = prim(a);
            //printf("%.f\n", fabs(b-a));
            if(fabs(b-a) < 0.0001) break;
            a = b;
            //printf("      %.f\n", a);
        }
        printf("%.3f\n", a);
    }
    return 0;
}

posted on 2012-09-04 22:20  louzhang_swk  阅读(221)  评论(0编辑  收藏  举报