POJ-2728-Desert King

POJ-2728-Desert King

http://poj.org/problem?id=2728

有N个村庄,给出每个村庄的坐标和海拔,,benifit为两点之间的距离,cost为两点的高度差,现在要求一棵树使得 cost / benift 最小,即求一个最优比例生成树

第一次遇见这种生成树,在网上找了个解法

假设sigma(h)/sigma(l)==K均值K可取,即: sigma(h)==K*sigma(l)

sigma(h)==K*(l1+l2+l3+...lm)

sigma(h)==K*l1+K*l2+K*l3+...K*lm

把原来的每个边的h都减去K*l

即hi'=hi-li'==hi-li*K

然后问题可以转换到求hi'这些边的最小生成树了

如果hi'这些边得最小生成树权值和<=0.0,说明K这个均值可取

对于k,二分求解即可

代码基本是模仿网上的

#include
#include
#include
#include
#include
using namespace std;
#define MAXN 1010
#define INF 9999999999
struct Point
{
	double x,y,h;
};
Point point[MAXN];
double mat[MAXN][MAXN];
double h[MAXN][MAXN];
double l[MAXN][MAXN];
int n;
double head,tail;
double dist(Point &a,Point &b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double prim()
{
	int i,j,k;
	double ans=0.0,min;
	int visit[MAXN];
	double dis[MAXN];
	for(i=0;imat[k][j])
		dis[j]=mat[k][j];
	}
	return ans;
}
int main()
{
	int i,j;
	double maxc,minc,maxl,minl,mid;
	while(scanf("%d",&n),n)
	{
		maxc=-INF;
		minc=INF;
		maxl=-INF;
		minl=INF;
		for(i=0;ih[i][j])
			minc=h[i][j];
			if(maxll[i][j])
			minl=l[i][j];
		}
		head=minc/maxl;
		tail=maxc/minl;
		while(tail-head>1e-4)
		{
			mid=(head+tail)/2;
			for(i=0;i


你可能感兴趣的:(POJ-2728-Desert King)