http://acm.hdu.edu.cn/showproblem.php?pid=4081
有n坐城市,输入每坐城市的坐标和人口。
现在要在所有城市之间修路,保证每个城市都能相连,并且保证A/B 最大,所有路径的花费和最小
A是某条路i两端城市人口的和
B表示除路i以外所有路的花费的和(路径i的花费为0)
#include<stdio.h>
#include<string.h>
#include<math.h>
#define M 1005
#define INF 100000000.0
struct node
{
int x,y,p;
}po[M];
int n;
double dis[M][M];
double MIN[M];
double max_val[M][M];
int pre[M];
bool v[M];
double tot_val;
double getlen(node a,node b)
{
double len=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
return sqrt(len*1.0);
}
void Init()
{
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<i;j++)
{
max_val[i][j]=max_val[j][i]=0;
dis[i][j]=dis[j][i]=getlen(po[i],po[j]);
}
}
void prim()
{
int i,j,k;
double mn;
for(i=1;i<=n;i++)
{
MIN[i]=INF;
pre[i]=i;
v[i]=false;
}
MIN[1]=0;
tot_val=0;
for(i=1;i<=n;i++)
{
mn=INF;
for(j=1;j<=n;j++)
if(!v[j]&&MIN[j]<mn)
{
k=j;
mn=MIN[j];
}
tot_val+=mn;
int u=pre[k];
for(j=1;j<=n;j++)
if(v[j])
{
if(max_val[j][u]<mn)
max_val[j][k]=max_val[k][j]=mn;
else max_val[j][k]=max_val[k][j]=max_val[j][u];
//printf("---%d %d %f\n",j,k,max_val[j][k]);
}
v[k]=true;
for(j=1;j<=n;j++)
if(!v[j]&& MIN[j]>dis[j][k])
{
MIN[j]=dis[j][k];
pre[j]=k;
}
}
}
double solve()
{
int i,j;
int A;
double max=-1,B;
for(i=1;i<=n;i++)
for(j=1;j<i;j++)
{
A=po[i].p+po[j].p;
B=tot_val-max_val[i][j];
if(max<(A*1.0/B)) max=A*1.0/B;
}
return max;
}
int main()
{
int t;
int i;
double ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d%d%d",&po[i].x,&po[i].y,&po[i].p);
Init();
prim();
ans=solve();
printf("%.2f\n",ans);
}
return 0;
}