秦始皇统一中国之后要在全国修公路连接各个城市,皇帝只想修成最小生成树(距离最小,不考虑人力),一个道士说自己可以不花人力物力修一条路,经过两方妥协,选择max(两个城市人口/(生成树长度-这条路的长度(连接两个城市的路中,权值最大的那段路)))的路让他变,求这个比值最大值。
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define rap(i, a, n) for(int i=a; i<=n; i++) #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int maxn = 1010, INF = 0x7fffffff; int n; int pre[maxn], vis[maxn]; double graph[maxn][maxn], maxd[maxn][maxn], d[maxn]; struct node { int x, y, p; }Node[maxn]; double prime(int s) { double sum = 0; mem(vis, 0); mem(maxd, 0); int temp; rap(i, 1, n) d[i] = graph[s][i], pre[i] = s; d[s] = 0; vis[s] = 1; rap(i, 1, n-1) { double mincost = INF; rap(j, 1, n) if(!vis[j] && mincost > d[j]) { temp = j; mincost = d[j]; } rap(j, 1, n) if(vis[j] && j != temp) maxd[temp][j] = maxd[j][temp] = max(mincost, maxd[pre[temp]][j]); sum += mincost; vis[temp] = 1; // used[temp][pre[temp]] = used[pre[temp]][temp] = 1; rap(j, 1, n) { if(!vis[j] && d[j] > graph[temp][j]) d[j] = graph[temp][j], pre[j] = temp; } } return sum; } int main() { int T; scanf("%d", &T); while(T--) { //求次小生成树还是得需要这段代码,用来找到不在生成树里的边 // scanf("%d", &n); // for(int i=1; i<=n; i++) // for(int j=1; j<=n; j++) // if(i == j) graph[i][j] = 0; // else graph[i][j] = graph[j][i] = INF; rap(i, 1, n) { scanf("%d%d%d", &Node[i].x, &Node[i].y, &Node[i].p); } rap(i, 1, n) rap(j, i+1, n) graph[i][j] = graph[j][i] = sqrt((double)(Node[i].x - Node[j].x)*(Node[i].x - Node[j].x) + (double)(Node[i].y - Node[j].y)*(Node[i].y - Node[j].y)); double dis = prime(1); double sum = -1; rap(i, 1, n) rap(j, i+1, n) if(pre[i] == j || pre[j] == i) //对于当前结点i和j 如果i和j之间有直接边(在生成树中的) 则dis减直接边 sum = max(sum, 1.0*(Node[i].p + Node[j].p)/(dis - graph[i][j])); else //没有直接边 则减i和j之间那条路中权值最大的那段路 sum = max(sum, 1.0*(Node[i].p + Node[j].p)/(dis - maxd[i][j])); printf("%.2f ", sum); } return 0; }