POJ 2728 Desert King

 

最优比率生成树。

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;
}

 

你可能感兴趣的:(des)