hdu4081

次小生成树的裸题

#include <bits/stdc++.h>
using namespace std;

const int inf = 0x3f3f3f3f;
const int N = 1010;

double g[N][N], mincost[N], cost[N], pos[N][2], path[N][N];
double radio, A, B;
int pre[N], n;
bool vis[N], used[N][N];

double cal_dis(double x1, double y1, double x2, double y2){
	return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

void prim(){
	A = B = 0;
	memset(vis, false, sizeof(vis));
	memset(used, false, sizeof(used));
	memset(path, 0, sizeof(path));
	vis[1] = true;
	for(int i = 1; i <= n; i ++){
		mincost[i] = g[1][i];
		pre[i] = 1;
	}
	for(int i = 1; i < n; i ++){
		int u = -1;
		for(int j = 1; j <= n; j ++){
			if(! vis[j]){
				if(u == -1 || mincost[j] < mincost[u])
					u = j;
			}
		}
		used[u][pre[u]] = used[pre[u]][u] = true;
		B += g[pre[u]][u];
		vis[u] = true;
		for(int j = 1; j <= n; j ++){
			if(vis[j] && j != u){
				path[u][j] = path[j][u] = max(path[j][pre[u]], mincost[u]);
			}
			if(! vis[j]){
				if(mincost[j] > g[u][j]){
					mincost[j] = g[u][j];
					pre[j] = u;
				}
			}
		}
	}
}
int main(){
	int T;
	scanf("%d", &T);
	while(T --){
		scanf("%d", &n);
		memset(g, 0, sizeof(g));
		for(int i = 1; i <= n; i ++){
			scanf("%lf %lf %lf", &pos[i][0], &pos[i][1], &cost[i]);
		}
		for(int i = 1; i <= n; i ++){
			for(int j = 1; j <= n; j ++){
				if(i != j){
					g[i][j] = cal_dis(pos[i][0], pos[i][1], pos[j][0], pos[j][1]);
				}
			}		
		}
		prim();
		radio = -inf;
		for(int i = 1; i <= n; i ++){
			for(int j = 1; j <= n; j ++){
				if(i != j){
					if(used[i][j]){
						radio = max(radio, (cost[i] + cost[j]) / (B - g[i][j]));
					}
					else{
						radio = max(radio, (cost[i] + cost[j]) / (B - path[i][j]));
					}
				}
			}
		}
		printf("%.2f\n", radio);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/82594650