枚举+最小生成树 hdoj4081 Qin Shi Huang's National Road System
来源:互联网 发布:毕业论文的数据分析 编辑:程序博客网 时间:2024/06/05 13:52
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4081
题目大意是给你一个图,既有点权又有边权,求一个生成树,你可以任选其中一条边,使它的边权为0,最终使得边权为0的两点的点权和/剩余边的边权和 最小。
我们可以这样思考,从最小生成树中去掉一条边,剩余的两个连通分量用边权为0的边链接。这样是正确的,因为如果你要选择两个点并用0边把它们连接起来,意味着需要在此基础上做一颗最小生成树,求最小生成树的算法是贪心的,因此在此基础上的最小生成树除了0边之外,其他边的集合是原来最小生成树的子集(或者如果存在多棵最小生成树,边权和是相同的)。接下来就是选择0边连接哪两个节点的问题了,显然连接两个点权最大的节点。枚举删去n-1条边,取最大的即是答案。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <vector>using namespace std;const int MAX = 1005;const double INF = 1e10;double map[MAX][MAX], xx[MAX], yy[MAX];int n, p[MAX], vis[MAX], fu, fv, pmax;struct edge { int u, v; double w;} dis[MAX], e[MAX];vector<int> ve[MAX];void init(void){ memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i ++) ve[i].clear(); pmax = 0;}inline double dist(double x1, double y1, double x2, double y2){ return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));}int dfs(int x){ vis[x] = 1; if (p[x] > pmax) pmax = p[x]; for (int i = 0; i < ve[x].size(); i ++) { if (!vis[ve[x][i]] && !(fu == x && fv == ve[x][i] || fu == ve[x][i] && fv == x)) { dfs(ve[x][i]); } }}double prim(void){ double ret = 0; vis[1] = 1; for (int i = 1; i <= n; i ++) { dis[i].w = map[1][i]; dis[i].u = 1; dis[i].v = i; } for (int i = 1; i <= n - 1; i ++) { double min = INF; int minid; for (int j = 1; j <= n; j ++) { if (!vis[j] && dis[j].w < min) { min = dis[j].w; minid = j; } } vis[minid] = 1; ret += min; e[i] = dis[minid]; ve[e[i].u].push_back(e[i].v); ve[e[i].v].push_back(e[i].u); for (int j = 1; j <= n; j ++) { if (!vis[j] && dis[j].w > map[minid][j]) { dis[j].w = map[minid][j]; dis[j].u = minid; } } } return ret;}int main(){ int t; scanf("%d",&t); while (t --) { init(); scanf("%d",&n); for (int i = 1; i <= n; i ++) { scanf("%lf%lf%d",&xx[i], &yy[i], &p[i]); for (int j = 1; j < i; j ++) { map[i][j] = map[j][i] = dist(xx[i], yy[i], xx[j], yy[j]); } map[i][i] = INF; } double len = prim(); double ans = -INF; int pp; for (int i = 1; i <= n - 1; i ++) { memset(vis, 0, sizeof(vis)); pmax = 0; fu = e[i].u; fv = e[i].v; dfs(fu); pp = 0; pp += pmax; memset(vis, 0, sizeof(vis)); pmax = 0; dfs(fv); pp += pmax; ans = max(ans, pp / (len - e[i].w)); } printf("%.2lf\n", ans); } return 0;}
阅读全文
0 0
- 枚举+最小生成树 hdoj4081 Qin Shi Huang's National Road System
- HDU4081 Qin Shi Huang's National Road System【prim最小生成树+枚举】
- HDU 4081 Qin Shi Huang's National Road System(最小生成树+暴力枚举边)
- LA5713 Qin Shi Huang's National Road System 生成树
- HDU 4081Qin Shi Huang's National Road System(最小生成树+最小瓶颈路)
- HDU 4081 Qin Shi Huang's National Road System (枚举次小生成树)
- hdu 4081 Qin Shi Huang's National Road System 最小生成树
- HDU 4081 Qin Shi Huang's National Road System 最小/次小生成树的性质
- HDU 4081 Qin Shi Huang's National Road System 最小生成树变形
- hdu4081 Qin Shi Huang's National Road System 最小生成树+DFS★★
- 【UVALive】5713 Qin Shi Huang's National Road System 最小生成树
- hdu 4081Qin Shi Huang's National Road System(最小生成树变形)
- UVa - 1494 Qin Shi Huang's National Road System(最小生成树)
- Hdu 4081 Qin Shi Huang's National Road System(最小生成树)
- HDU 4081 Qin Shi Huang's National Road System 最小生成树
- HDU-4081 Qin Shi Huang's National Road System(最小生成树)
- HDU-4081 Qin Shi Huang's National Road System(最小生成树[Prim])
- uva 1494 - Qin Shi Huang's National Road System(最小生成树)
- 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
- 链表查找
- js随机生成十六进制和rgb的颜色
- 【Codeforces 807 B. T-Shirt Hunt】
- finereport 组件
- 枚举+最小生成树 hdoj4081 Qin Shi Huang's National Road System
- pc:get 增加支持urlrule的解决办法
- 一个Swifter的Kotlin学习——Kotlin 基本语法
- Deepin Software编程
- Eclipse设置背景颜色、字体及代码提示
- 魔族密码(Vijos-1028)
- 教你快速使用AndroidStudio制作出一张合格.9图片
- 单链表逆置
- 执行脚本出现bin/bash: bad interpreter: No such file or directory