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