POJ 2728 Desert King

大意不再赘述。

思路:0\1分数规划,最优比率生成树,注意输出要用.3f,不然WA。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;

const int MAXN = 1010;
const int MAXM = 5010;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;

struct node
{
	double x, y;
	double h;
}a[MAXN];

double w[MAXN][MAXN];
double d[MAXN];

int n, m;

void init()
{
	memset(w, INF, sizeof(w));
}

double dist(const node &a, const node &b)
{
	return sqrt(pow(a.x-b.x, 2.0) + pow(a.y-b.y, 2.0));
}

double Prim(int src)
{
	bool vis[MAXN] = {0};
	for(int i = 1; i <= n; i++) d[i] = (i == src)? 0:INF;
	double cnt = 0;
	for(int i = 1; i <= n; i++)
	{
		int x;
		double m = INF;
		for(int y = 1; y <= n; y++) if(!vis[y] && m > d[y]) m = d[x=y];
		vis[x] = 1;
		cnt += m;
		for(int y = 1; y <= n; y++) d[y] = min(d[y], w[x][y]);
	}
	return cnt;
}

int read_case()
{
	scanf("%d", &n);
	if(!n) return 0;
	for(int i = 1; i <= n; i++)
	{
		scanf("%lf%lf%lf", &a[i].x, &a[i].y, &a[i].h);
	}
	return 1;
}

void build(double mid)
{
	init();
	for(int i = 1; i <= n; i++)
	{
		for(int j = i+1; j <= n; j++)
		{
			w[i][j] = w[j][i] = fabs(a[i].h-a[j].h) - mid * dist(a[i], a[j]); 
		}
	}
}

void solve()
{
	double x = 0, y = 100;
	while(y-x > eps)
	{
		double mid = x+(y-x)/2.0;
		build(mid);
		double ans = Prim(1);
		if(ans > 0) x = mid;
		else y = mid;
	}
	printf("%.3f\n", x);
}

int main()
{
	while(read_case())
	{
		solve();
	}
	return 0;
}


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