题意:给你一些坐标以及坐标的权值ci,求一棵生成树,使(∑xi×ci)/(∑xi×bi)最小
思路:听说楼教主当年1a了这题,前来膜拜….
这题是最优比率生成树
http://blog.acmj1991.com/?p=747
#include<stdio.h>
#include<string.h>
#define maxN 1010
#define inf 100
int xx[maxN],yy[maxN],key[maxN],cost[maxN][maxN],pre[maxN];
double len[maxN][maxN],map[maxN][maxN],dis[maxN];
bool vist[maxN],f[maxN][maxN];
int abs(int x){return x>0?x:-x;}
double getlen(int u,int v)
{
return (xx[u]-xx[v])*(xx[u]-xx[v])-(yy[u]-yy[v])*(yy[u]-yy[v]);
}
double prim(int n,double l)
{
memset(vist,false,sizeof(vist));
memset(f,false,sizeof(f));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
map[i][j]=map[j][i]=abs(cost[i][j]-l*len[i][j]);
for(int i=2;i<=n;i++)
{
dis[i]=map[1][i];
pre[i]=1;
}
vist[1]=true;
for(int h=1;h<n;h++)
{
double minn=inf;
int k;
for(int i=2;i<=n;i++)
if(!vist[i]&&minn>dis[i])
minn=dis[i],k=i;
vist[k]=true;
f[pre[k]][k]=f[k][pre[k]]=true;
for(int i=1;i<=n;i++)
if(!vist[i]&&dis[i]>map[i][k]){
dis[i]=map[i][k];
pre[i]=k;
}
}
double csum=0.0,lsum=0.0;
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
if(f[i][j]||f[j][i])
csum+=cost[i][j],lsum+=len[i][j];
return csum/lsum;
}
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
double sum;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&xx[i],&yy[i],&key[i]);
for(int j=1;j<=i;j++)
{
len[i][j]=len[j][i]=getlen(i,j);
cost[i][j]=cost[j][i]=abs(key[i]-key[j]);
}
}
double rate=40.0;
while(1)
{
double temp=prim(n,rate);
if(rate==temp)break;
}
printf("%lf\n",rate);
}
}