【题目分析】
最优比率生成树。
【代码】
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps=1e-4;
double x[1001],y[1001],z[1001],dis[1001];
double v[1001][1001],c[1001][1001];
int n,tmp,in[1001];
inline bool test(double mid)
{
double ans=0,minn;
memset(in,0,sizeof in);
dis[1]=0;in[1]=1;
for (int i=2;i<=n;++i) dis[i]=c[1][i]-v[1][i]*mid;
for (int i=1;i<n;++i)
{
minn=0x7f7f7f7f;
for (int j=1;j<=n;++j)
if (!in[j]&&dis[j]<minn)
{
minn=dis[j];
tmp=j;
}
in[tmp]=1;
ans+=dis[tmp];
for (int j=1;j<=n;++j)
dis[j]=min(dis[j],c[tmp][j]-v[tmp][j]*mid);
}
return ans<=eps;
}
int main()
{
while (scanf("%d",&n)!=EOF&&n)
{
for (int i=1;i<=n;++i) scanf("%lf%lf%lf",&x[i],&y[i],&z[i]);
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
{
v[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
c[i][j]=sqrt((z[i]-z[j])*(z[i]-z[j]));
}
double l=0,r=100;
while (l+eps<=r)
{
double mid=(l+r)/2;
if (test(mid)) r=mid;
else l=mid;
}
printf("%.3f\n",l);
}
}