题目的意思是:n个城市,需要修建一些道路使得任意两个城市联通,还可以修一条魔法道路, 不花钱, 设魔法路连接的城市的人口之和为A, 所有道路总长为B, 求A/B的最大值
也用到了D[i][j]数组。。。不难不难。。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define MAXN (1000+5)
struct node{
int u, v, dis;
bool operator <(const node &x)const{
return dis < x.dis;
}
};
int X[MAXN], Y[MAXN], peo[MAXN], f[MAXN], D[MAXN][MAXN];
vector<node> G[MAXN];
node edges[MAXN*MAXN];
bool vis[MAXN];
void init(){
for(int i = 0; i < MAXN; i++) G[i].clear(), f[i] = i;
memset(D, 0, sizeof(D));
}
int calc(int x1, int y1, int x2, int y2){
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int find(int x){
return x == f[x]? x: (f[x] = find(f[x]));
}
void Bspfa(int s){
memset(vis, 0, sizeof(vis));
queue<int> q;
q.push(s); D[s][s] = 0; vis[s] = true;
while(!q.empty()){
int now = q.front(); q.pop();
for(int i = 0; i < G[now].size(); i++){
node next = G[now][i];
int v = G[now][i].v, dis = G[now][i].dis;
if(vis[v]) continue;
D[s][v] = max(D[s][now], dis);
q.push(v);
vis[v] = true;
}
}
}
int main(){
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
int T;
scanf("%d", &T);
while(T--){
init();
int n, m = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d%d%d", &X[i], &Y[i], &peo[i]);
for(int j = 1; j < i; j++)
edges[++m] = ((node){i, j, calc(X[i], Y[i], X[j], Y[j])});
}
sort(edges+1, edges+m+1);
double sum = 0;
int tot = 0;;
for(int i = 1; i <= m; i++){
node now = edges[i];
int u = now. u, v = now.v, dis = now.dis;
int x = find(u), y = find(v);
if(x == y) continue;
f[x] = y;
G[x].push_back((node){x, y, dis});
G[y].push_back((node){y, x, dis});
sum += sqrt((double)dis); tot++;
if(tot >= n-1) break;
}
for(int i = 1; i <= n; i++) Bspfa(i);
double ans = 0;
for(int i = 1; i <= n; i++)
for(int j = i+1; j <= n; j++)
ans = max(ans, (peo[i]+peo[j])*1.0 / (sum-sqrt(D[i][j])));
printf("%.2lf\n", ans);
}
return 0;
}