poj 2728 Desert King(最優比例生成樹)

題意:給你一些座標以及座標的權值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);
	}
}        


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章