题目大意:最优比例生成树,分子为两点间的垂直距离,分母为欧几米德距离;
题目解析:用迭代+prim,更新dist,dist为abs(ax-b.x)-ans*dist(a,b);(题目输出只能用f不能用lf)
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1010;
struct node
{
int x,y,z;
}q[maxn];
double dis(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int n;
double dist[maxn];
bool vis[maxn];
int pre[maxn];
double prime(double x)
{
memset(vis,0,sizeof(vis));
for(int i=2;i<=n;i++)
{
dist[i]=abs(q[i].z-q[1].z)-x*dis(q[i],q[1]);
pre[i]=1;
}
vis[1]=1;
dist[1]=0;
pre[1]=1;
double cost=0,length=0;
for(int i=1;i<n;i++)
{
double mi=100000000;
int u=-1;
for(int j=1;j<=n;j++)
{
if(vis[j]) continue;
if(mi>dist[j])
{
u=j;
mi=dist[j];
}
}
vis[u]=1;
cost+=abs(q[pre[u]].z-q[u].z);
length+=dis(q[pre[u]],q[u]);
for(int j=1;j<=n;j++)
{
double temp=abs(q[u].z-q[j].z)-x*dis(q[j],q[u]);
if(!vis[j]&&temp<dist[j])
{
dist[j]=temp;
pre[j]=u;
}
}
}
return cost/length;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z);
}
double a=0,b;
while(1)
{
b=prime(a);
if(abs(a-b)<1e-4) break;
a=b;
}
printf("%.3f\n",a);
}
return 0;
}