首页 > 代码库 > HDU 4081 Qin Shi Huang's National Road System 次小生成树
HDU 4081 Qin Shi Huang's National Road System 次小生成树
给你n个城市 每个城市有一定数量的人 连接2个城市需要的花费是他们之间的距离 现在要建一颗最小生成树 可以免费建其中一条边 设A为免费的那条边连接的2个城市的人口之和 B为修建的最小生成树的花费 求最大的A/B
先求最小生成树 设总花费为totol 然后可以枚举免费的那条边 枚举边等于A确定 在这条在最小生成树里的情况下 求最小的B
如果这条边是最小生成树里的边 那么很容易求得B 拿totol减去这条边就行了
如果不是 那么把这条边加到最小生成树 会出现一个环 找到这个环最大的那条边剪掉 就是次小生成树的做法 然后类似求A/B
n^2预处理任意2点之间唯一路径上的最大边权
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> using namespace std; const int maxn = 1010; struct poit { double x, y, p; }p[maxn]; struct edge { double dis; int u, v, next; bool select; }e[maxn*maxn], G[maxn*2]; struct node { double dis; int u, v; node(){} node(int u, int v, double d): u(u), v(v), dis(d) {} }; int n; double dp[maxn][maxn], totol; int f[maxn]; int first[maxn], cnt; void AddEdge(int u, int v, double w) { G[cnt].u = u; G[cnt].v = v; G[cnt].dis = w; G[cnt].next = first[u]; first[u] = cnt++; G[cnt].u = v; G[cnt].v = u; G[cnt].dis = w; G[cnt].next = first[v]; first[v] = cnt++; } void init() { for(int i = 1; i <= n; i++) f[i] = i; totol = 0; memset(dp, 0, sizeof(dp)); memset(first, -1, sizeof(first)); cnt = 0; } int find(int x) { if(x != f[x]) return f[x] = find(f[x]); return f[x]; } double Dist(int i, int j) { return sqrt((double)(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)); } bool cmp(edge a, edge b) { return a.dis < b.dis; } void MST(int l) { for(int i = 0; i < l; i++) { int x = find(e[i].u); int y = find(e[i].v); if(x != y) { totol += e[i].dis; f[x] = y; e[i].select = true; AddEdge(e[i].u, e[i].v, e[i].dis); } } } void BFS(int x) { queue <node> Q; Q.push(node(-1, x, 0)); while(!Q.empty()) { node u = Q.front(); Q.pop(); for(int i = first[u.v]; i != -1; i = G[i].next) { if(G[i].v == u.u) continue; double temp = max(u.dis, G[i].dis); dp[x][G[i].v] = max(dp[x][G[i].v], temp); Q.push(node(u.v, G[i].v, temp)); } } } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); init(); for(int i = 1; i <= n; i++) scanf("%lf %lf %lf", &p[i].x, &p[i].y, &p[i].p); int l = 0; for(int i = 1; i <= n; i++) { for(int j = i+1; j <= n; j++) { if(i == j) continue; e[l].u = i; e[l].v = j; e[l].select = false; e[l].dis = Dist(i, j); l++; } } sort(e, e+l, cmp); MST(l); for(int i = 1; i <= n; i++) BFS(i); double ans = 0.0; for(int i = 0; i < l; i++) { int u = e[i].u, v = e[i].v; if(e[i].select) { double tmp = (p[u].p + p[v].p) / (totol-e[i].dis); ans = max(ans, tmp); } else { double tmp = (p[u].p + p[v].p) / (totol-dp[u][v]); ans = max(ans, tmp); } } printf("%.2lf\n", ans); } return 0; }
HDU 4081 Qin Shi Huang's National Road System 次小生成树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。