POJ 2728 最优比率生成树

题意:
     让你求一颗最小比率生成树。
思路:
     我总结过了,在这里:http://blog.csdn.net/u013761036/article/details/26666261

     提示几个地方,这个题目的最小树记得用普利姆,别用克鲁斯卡尔,克鲁斯卡尔会超时,在sort那个地方超时。别的没啥。


#include<stdio.h>
#include<math.h>

#define INF 1000000000
#define eps 0.0001

typedef struct
{
   double x ,y ,z;
}NODE;

NODE node[1100];
int mark[1100];
double d[1100];

double diss(NODE a ,NODE b)
{
   double tmp = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
   return sqrt(tmp);
}

double abss(double x)
{
   return x > 0 ? x : -x;
}

double Prim(int n ,double L)
{
   double ans = 0;
   for(int i = 2 ;i <= n ;i ++)
   {
      double dis  = diss(node[1] ,node[i]);
      //d[i] = dis  - L * abss(node[1].z - node[i].z);
      d[i] = abss(node[1].z - node[i].z) - L * dis;
      mark[i] = 0;
   }
   mark[1] = 1;
   for(int ii = 1 ;ii < n ;ii ++)
   {
      double Min = INF;
      int mk = -1;
      for(int i = 1 ;i <= n ;i ++)
      {
         if(!mark[i] && d[i] < Min)
         {
            mk = i;
            Min = d[i];
         }
      }
      if(mk == -1) return ans; 
      ans += Min;
      mark[mk] = 1;
      for(int i = 1 ;i <= n ;i ++)
      {
          if(mark[i]) continue;
          double dis  = diss(node[mk] ,node[i]);
          //double tmp = dis  - L * abss(node[mk].z - node[i].z);
          double tmp = abss(node[mk].z - node[i].z) - dis * L;
          if(d[i] > tmp) d[i] = tmp;
      }
   }
   return ans;
}


int main ()
{
   int n ,m ,i ,j;
   while(~scanf("%d" ,&n) && n)
   {
      for(i = 1 ;i <= n ;i ++)
      scanf("%lf %lf %lf" ,&node[i].x ,&node[i].y ,&node[i].z);
      double low ,up ,mid ,ans = 0;
      low = 0 ,up = INF;
      while(up - low >= eps)
      {
         mid = (low + up) / 2;
         double tmp = Prim(n ,mid);
         if(tmp >= 0)
         ans = low = mid;
         else up = mid;
      }
      printf("%.3f\n" ,ans);
   }
   return 0;
}
   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值