最优比率生成树。

CODE:

 

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace std;

#define eps 1e-4
const int INF = 0x3f3f3f3f;
const int MAXN = 1010;

double w[MAXN][MAXN], d[MAXN];
double dis[MAXN][MAXN], cost[MAXN][MAXN];

int n, m;

struct node
{
    double x, y, z;
}a[MAXN];

double dist(const node a, const node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

void init()
{
    memset(w, INF, sizeof(w));
}


double Prim(int src)
{
    double cnt = 0;
    bool vis[MAXN] = {0};
    for(int i = 1; i <= n; i++) d[i] = (i == src)?0:INF;
    for(int i = 1; i <= n; i++)
    {
        int x;
        double m = INF;
        for(int y = 1; y <= n; y++) if(!vis[y] && d[y] < m) m = d[x=y];
        vis[x] = 1;
        cnt += m;
        for(int y = 1; y <= n; y++) if(!vis[y] && d[y] > w[x][y])
        {
            d[y] = w[x][y];
        }
    }
    return cnt;
}

double BSearch()
{
    double x = 0, y = 100;
    while((y-x) > eps)
    {
        double mid = x+(y-x)/2;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++) if(i != j)
            {
                w[i][j] = w[j][i] = cost[i][j] - dis[i][j]*mid;
            }
        }
        double t = Prim(1);
        if(t > 0) x = mid;
        else y = mid;
    }
    return x;
}

int main()
{
    while(scanf("%d", &n) && n)
    {
        init();
        for(int i = 1; i <= n; i++)
        {
            scanf("%lf%lf%lf", &a[i].x, &a[i].y, &a[i].z);
        }
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++) if(i != j)
            {
                cost[i][j] = cost[j][i] = fabs(a[i].z - a[j].z);
                dis[i][j] = dis[j][i] = dist(a[i], a[j]);
            }
        }
        double ans = BSearch();
        printf("%.3lf\n", ans);
    }
    return 0;
}

 

posted on 2012-10-24 19:03  有间博客  阅读(145)  评论(0编辑  收藏  举报