I can see this question in the LRJ book. Today I will go back and continue reading this question. I have found many things I have understood. There are N cities, and each city has a coordinate and population. Now we need to build some edges so that they can connect to each other. The cost is the length of these edges, and then one edge is free of charge. After a free edge is asked, the length of the population/remaining edge of the two cities with the free edge is the largest. Idea: first perform the MST operation. After finding the MST, we enumerate each edge to see if it can be deleted, that is, it is free of charge. So what is the impact on the MST after deleting an edge. First, we assume that a free (delete) edge a-> B has the weight c. If this edge is an edge on the MST, we can only delete this edge. If this edge is not an edge on the MST, we can delete the edge with the largest a-> B weight, because we want to minimize the remaining length.
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <stack> #include <set> #include <map> #include <queue> #include <algorithm> #define ll long long #define inf 1<<30 #define PI acos(-1.0) #define mem(a , b) memset(a , b ,sizeof(a)) using namespace std ; struct kdq { int s , e ; double l ; bool operator < (const kdq & fk)const { return l > fk.l ; } } ; inline void RD(int &ret) { char c; int flag = 1 ; do { c = getchar(); if(c == '-')flag = -1 ; } while(c < '0' || c > '9') ; ret = c - '0'; while((c=getchar()) >= '0' && c <= '9') ret = ret * 10 + ( c - '0' ); ret *= flag ; } #define N 1111 double ed[N][N] , edM[N][N] ; int x[N] , y[N], pop[N] ; int n ; double mst = 0 ; double getdis(int i ,int j) { return sqrt(1.0 * (x[i] - x[j]) * (x[i] - x[j]) + 1.0 * (y[i] - y[j]) * (y[i] - y[j])) ; } void init() { cin >> n ; for (int i = 1; i <= n ; i ++ ) { RD(x[i]) ; RD(y[i]) ; RD(pop[i]) ; } for (int i = 1 ; i <= n ; i ++ ) { for (int j = 1; j <= n ; j ++ ) { if(i == j)ed[i][j] = 0 ; else ed[i][j] = getdis(i , j) ; } } mst = 0 ; } double dis[N] ; int vis[N] ; bool ok[N][N] ; vector<int>E[N] ; void prim() { priority_queue<kdq>qe ; for (int i = 1 ; i <= n ; i ++ ) { dis[i] = ed[1][i] ; E[i].clear() ; } mem(vis ,0) ; mem(ok ,0) ; for (int i = 1 ; i <= n ; i ++ ) { qe.push((kdq) {1 , i , ed[1][i]}) ; } dis[1] = 0 , vis[1] = 1 ; while(!qe.empty()) { kdq tp = qe.top() ; qe.pop() ; if(vis[tp.e])continue ; mst += ed[tp.s][tp.e] ; vis[tp.e] = 1 ; ok[tp.s][tp.e] = ok[tp.e][tp.s] = 1 ; E[tp.s].push_back(tp.e) ; E[tp.e].push_back(tp.s) ; for (int i = 1 ; i <= n ; i ++ ) { if(!vis[i] && dis[i] > ed[tp.e][i]) { dis[i] = ed[tp.e][i] ; qe.push((kdq){tp.e , i , ed[tp.e][i]}) ; } } } } void dfs(int root ,int fa ,int now ,double MAX) { edM[root][now] = MAX ; int sz = E[now].size() ; for (int i = 0 ; i < sz ; i ++ ) { int e = E[now][i] ; if(e == fa)continue ; dfs(root , now , e , max(MAX , ed[now][e])) ; } } void solve() { init() ; prim() ; for (int i = 1 ; i <= n ; i ++ ) { dfs(i , -1 , i , 0) ; } double ans = -1 ; for (int i = 1 ; i <= n ; i ++ ) { for (int j = 1 ; j < i ; j ++ ) { if(ok[i][j]) ans = max(ans , (pop[i] + pop[j]) * 1.0 / (mst - ed[i][j])) ; else ans = max(ans , (pop[i] + pop[j]) * 1.0 / (mst - edM[i][j])) ; } } printf("%.2f\n",ans) ; } int main() { int _ ;cin >> _ ;while(_ -- )solve() ; return 0; }