POJ 2728题

//最优比例生成树:使用迭代法求解
#include <stdio.h>
#include <string.h>
#include <math.h>
#define vilnum 1001
typedef struct node
{
 int x;
 int y;
 int z;
}node;  //定义村落的位置和海拔
const double eps = 0.0005; //定义精度,是最后一位的半个单位
node villages[vilnum];
double d[vilnum];
bool final[vilnum];
int pre[vilnum];   //定义节点的前驱
int N;
double price(node a,node b,double x) //重新定义最小生成树的权值
{
 return abs(a.z-b.z)-x*(sqrt(double(a.x-b.x)*(a.x-b.x)+double(a.y-b.y)*(a.y-b.y)));
}
double distance(node a,node b)   //定义村子之间的距离
{
 return sqrt(double(a.x-b.x)*(a.x-b.x)+double(a.y-b.y)*(a.y-b.y));
}
//prim算法:此处与以往编程不同,这里没有定义临界矩阵,而是使用前驱节点来代替
double prim(double x)
{
 int i,j;
 double min;
 double cost = 0;
 double length = 0;
 int v;
 memset(final,0,sizeof(final));
 for(i=1;i<N+1;++i)
 {
  d[i] = price(villages[1],villages[i],x);
  pre[i] = 1;  //初始化所有的节点的前驱为1
 }
 final[1] = true;
 d[1] = 0;
 for(i=1;i<N;++i)
 {
  min = 0x7fffffff; //定义最大值,double类型也可这样定义
  for(j=1;j<N+1;++j)
  {
   if(!final[j] && min>d[j])
   {
    min = d[j];
    v = j;
   }
  }
  final[v] = true;
  cost += abs(villages[pre[v]].z-villages[v].z); 
  length += distance(villages[pre[v]],villages[v]);
  for(j=1;j<N+1;++j)
  {
   if(!final[j] && d[j]>price(villages[j],villages[v],x))
   {
    d[j] = price(villages[j],villages[v],x);
    pre[j] = v;   //修改节点的前驱
   }
  }
 }
 return cost/length;
}
int main()
{
 //freopen("1.txt","r",stdin);
 int i,j;
 double start,next;
 while(scanf("%d",&N)!=EOF)
 {
  if(N==0)
   break;
  for(i=1;i<N+1;++i)
  {
   scanf("%d%d%d",&villages[i].x,&villages[i].y,&villages[i].z);
  }
  //迭代求解,从0开始
  start = 0;
  while(1)
  {
   next = prim(start);
   if(fabs(next-start)<=eps) //精度满足要求,停止迭代,fabs用于求浮点数的绝对值,abs用于求整数的绝对值
   {
    printf("%.3lf\n",next); //double类型的数的输出
    break;
   }
   start = next;
  }
 }
 return 0;
}

posted @ 2010-05-04 13:32  北海小龙  阅读(318)  评论(0编辑  收藏  举报