题目大意:秦始皇要在n个城市之间修筑一条道路使得任意两个城市均可连通。有个道士可以用法力帮忙修一条路。秦始皇希望其他的道路总长B最短且用法术连接的两个城市的人口之和A尽量大,因此下令寻找一个A / B的最大方案。(转自http://blog.csdn.net/murmured/article/details/18865721,侵删)
题解:考虑修哪一条路,此时A确定,断掉这条路后,形成两个连通块,不难发现两个连通块都应是MST才能让B最短。此时B为两个连通块的MST权值和
这个过程相当于选了一条路u->v后,在整张图的MST上,把MST上u->v路径上最大边删掉。
其实不用枚举边,枚举u和v即可
空间开小了,RE了无数发。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <map> 9 #include <string> 10 #include <cmath> 11 #define min(a, b) ((a) < (b) ? (a) : (b)) 12 #define max(a, b) ((a) > (b) ? (a) : (b)) 13 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a)) 14 template<class T> 15 inline void swap(T &a, T &b) 16 { 17 T tmp = a;a = b;b = tmp; 18 } 19 inline void read(int &x) 20 { 21 x = 0;char ch = getchar(), c = ch; 22 while(ch < ‘0‘ || ch > ‘9‘) c = ch, ch = getchar(); 23 while(ch <= ‘9‘ && ch >= ‘0‘) x = x * 10 + ch - ‘0‘, ch = getchar(); 24 if(c == ‘-‘) x = -x; 25 } 26 27 const int INF = 0x3f3f3f3f; 28 const int MAXN = 2000 + 10; 29 const int MAXM = 1000000 + 10; 30 31 int x[MAXM], y[MAXM], node[MAXM], n, m, t, u[MAXM], v[MAXM], cnt[MAXM], fa[MAXM], vis[MAXN]; 32 double ma[MAXN][MAXN], w[MAXM]; 33 struct Edge 34 { 35 int u,v,nxt; 36 double w; 37 Edge(int _u, int _v, double _w, int _nxt){u = _u;v = _v;w = _w;nxt = _nxt;} 38 Edge(){} 39 }edge[MAXM << 1]; 40 int head[MAXN], cntt; 41 inline void insert(int a, int b, double c) 42 { 43 edge[++cntt] = Edge(a,b,c,head[a]); 44 head[a] = cntt; 45 } 46 int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);} 47 int cmp(int x, int y){return w[x] < w[y];} 48 49 int tiaoshi; 50 void dfs(int x, int pre) 51 { 52 vis[x] = 1; 53 for(int pos = head[x];pos;pos = edge[pos].nxt) 54 { 55 int v = edge[pos].v; 56 if(v == pre) continue; 57 for(int i = 1;i <= n;++ i) 58 if(i == v || !vis[i]) continue; 59 else ma[i][v] =ma[v][i] = max(ma[i][v], max(ma[v][i], max(ma[x][i], max(ma[i][x], edge[pos].w)))); 60 dfs(v, x); 61 } 62 } 63 int main() 64 { 65 read(t); 66 for(;t;--t) 67 { 68 tiaoshi = 0; 69 read(n);memset(ma, 0, sizeof(ma)), memset(vis, 0, sizeof(vis)), memset(head, 0, sizeof(head)), cntt = 0, m = 0; 70 for(int i = 1;i <= n;++ i) read(x[i]), read(y[i]), read(node[i]); 71 for(int i = 1;i <= n;++ i) 72 for(int j = i + 1;j <= n;++ j) 73 ++ m, u[m] = i, v[m] = j, w[m] = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j])), cnt[m] = m, fa[m] = m; 74 std::sort(cnt + 1, cnt + 1 + m, cmp); 75 int tmp = 0; 76 double ans = 0; 77 double ans2 = 0; 78 for(int i = 1;i <= m;++ i) 79 { 80 int f1 = find(u[cnt[i]]), f2 = find(v[cnt[i]]); 81 if(f1 == f2) continue; 82 fa[f1] = f2; 83 insert(u[cnt[i]], v[cnt[i]], w[cnt[i]]), insert(v[cnt[i]], u[cnt[i]], w[cnt[i]]); 84 ans += w[cnt[i]]; 85 ++ tmp;if(tmp == n - 1) break; 86 } 87 dfs(1, -1); 88 for(int i = 1;i <= n;++ i) 89 for(int j = i + 1;j <= n;++j) 90 { 91 if(ans == ma[i][j]) continue; 92 ans2 = max(ans2, (double)(node[i] + node[j]) / (ans - ma[i][j])); 93 } 94 printf("%.2lf\n", ans2); 95 } 96 return 0; 97 }