UVALive - 5713
秦始皇要修建连通所有城市的路,一共有N个点以及各个点的坐标和人口。修建很多条路使N个城市连通,但是可以使其中一条路的修建费用为0。在修建费用最小的前提下,使得A/B最大。A指费用为0的路所连通的两个城市的人口和,B指除修建费用为0的路之外的所以路之和。
解题思路:因为要是整体的修建费用最小,必定要求他的最小生成树。但是可以使生成树中的一条边的费用为0,这样就不能简单的光求最小生成树。因为可以使连接某两个城市的路修建费用为0,所以可以枚举所有两个城市的组合。这样A的值就固定下来了,为了使得A/B最大。则需要删去这两个城市的连通路径中最长的边,使得B值越小。因为在这两个城市直接连边是不需要费用的。这样的话就和求次小生成树的算法有点像了。一开始把问题像的简单了,所以直接用了kruskal。但是求次小生成树还是prime算法比较方便。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const int maxx = 1005;
struct node
{int from, to;double len;node(int a, int b, double c){from = a, to = b, len = c;}node() {}bool operator<(const node &b){return len < b.len;}
}edge[maxx*maxx];
int x[maxx], y[maxx], people[maxx];
int fa[maxx];
double cost[maxx][maxx];
int cnt, n;
vector<pair<int, double>>G[maxx];
vector<int> path;void addedge(int a, int b)
{double now = sqrt(double((x[a] - x[b])*(x[a] - x[b]) + (y[a] - y[b])*(y[a] - y[b])));edge[++cnt] = node(a, b, now);
}int find(int now)
{if (fa[now] == now)return now;elsereturn fa[now] = find(fa[now]);
}double kru()
{double res = 0;for (int i = 1; i <= n; i++)G[i].clear();for (int i = 1; i <= cnt; i++){int xx = find(edge[i].from), yy = find(edge[i].to);if (xx != yy){res += edge[i].len;fa[xx] = yy;G[edge[i].from].push_back(make_pair(edge[i].to, edge[i].len));G[edge[i].to].push_back(make_pair(edge[i].from, edge[i].len));}}return res;
}void dfs(int v, int fa)
{path.push_back(v);for (int i = 0; i < G[v].size(); i++){int to = G[v][i].first;double now = G[v][i].second;if (to != fa){for (int j = 0; j < path.size(); j++){int eric = path[j];cost[to][eric] = cost[eric][to] = max(now, cost[eric][v]);}dfs(to, v);}}
}int main()
{int t;scanf("%d", &t);while (t--){cnt = 0;scanf("%d", &n);for (int i = 1; i <= n; i++)fa[i] = i;for (int i = 1; i <= n; i++)scanf("%d%d%d", &x[i], &y[i], &people[i]);for (int i = 1; i <= n; i++)for (int j = i + 1; j <= n; j++){addedge(i, j);}sort(edge + 1, edge + 1 + cnt);double sum = kru();double ans = 0;path.clear();memset(cost, 0, sizeof(cost));dfs(1, -1);for (int i = 1; i <= cnt; i++){int s = edge[i].from;int t = edge[i].to;double tmp = sum - cost[s][t];ans = max(ans, (people[s] + people[t] + 0.0) / tmp);}printf("%0.2f\n", ans);}return 0;
}
本人愚见,如有不足,欢迎指点~~
UVALive - 5713相关推荐
- UVALive - 5713 Qin Shi Huang's National Road System
prim + 邻接矩阵储存两点间最大距离,然后枚举即可. #include<iostream> #include<string> #include<cstdio> ...
- DP UVALive 6506 Padovan Sequence
题目传送门 /*题意:两行数字,相邻列一上一下,或者隔一列两行都可以,从左到右选择数字使和最大DP:状态转移方程:dp[i][j] = max (dp[i][j], dp[1-i][j-1] + a[ ...
- The UVALIVE 7716 二维区间第k小
The UVALIVE 7716 二维区间第k小 /** 题意:给一个n * n的矩阵,有q个查询每次查询r,c,s,k表示已(r,c)为右上角 大小为s的正方形中 第k小的元素n <= 250 ...
- UVALive 8513 lovers 2017 西安区域赛 B 贪心+multiset
UVALive 8513 有2种人,每个人有自己的权值$A_i$ $B_i$ 当$A_i + B_i >=K$时 两个人可以配对 问最多多少人可以配对 解法 : 把$/{ A_i /}$ 排序 ...
- 训练指南 UVALive - 3713 (2-SAT)
layout: post title: 训练指南 UVALive - 3713 (2-SAT) author: "luowentaoaa" catalog: true mathja ...
- 逆序数 UVALive 6508 Permutation Graphs
题目传送门 1 /* 2 题意:给了两行的数字,相同的数字连线,问中间交点的个数 3 逆序数:第一行保存每个数字的位置,第二行保存该数字在第一行的位置,接下来就是对它求逆序数 4 用归并排序或线段树求 ...
- Infinite Fraction Path UVALive - 8207
Infinite Fraction Path UVALive - 8207 题意: 给你n个数,每个数在0到9之间,每个数的下标一次是0~n-1,然后他所能走到的数为(i^2+1)%n,i为他本身的下 ...
- F - Heron and His Triangle UVALive - 8206
F - Heron and His Triangle UVALive - 8206 题意: 给你应该n,然后求一个最小的t,问长度为t-1,t,t+1所组成的三角形的面积为整数,t>=n 题解: ...
- Tree UVALive - 8212
Tree UVALive - 8212 题意: 有n个点,k个颜色,每个点都要被染色,相同颜色之间的边算是被该颜色覆盖,问有多少边被所有颜色覆盖 题解: 题目给的是无根树,我们可以将1默认为根然后求所 ...
- Rabbits UVALive - 8211
Rabbits UVALive - 8211 题意: n个兔子的位置,兔子每次可以跳到两个兔子之间,问最多可以跳多少下? 题解: 求出所有相邻两数的间隔,然后减去最小间隔就是答案 代码: #inclu ...
最新文章
- CLR中的IL、CTS和CLS总结
- ssis foreach 使用ADO记录集
- pythonopencv算法_python opencv之SURF算法示例
- knime实现python编写脚本
- .form文件_含文件上传的form表单AJAX提交小结
- JavaIO流中的拷贝
- Ubuntu 网速显示,ssh配置
- JSP教程第5讲笔记
- 如果看了此文你还不懂傅里叶变换,那就过来掐死我吧(完整版)
- 软件安装 | 神器VAX Patch VA_X.DLL 安装位置的问题 for VS2008 , VS2010 , VS2011
- 如何生成javadoc文档(JDK帮助文档)
- 谷歌升级街景采集车,用AI获取更佳图像
- 三极管串联线性稳压电路原理详解及Multisim仿真
- SDUT 第十届校赛H menhera酱那惨不忍睹的数学 【二分图 || 网络流】
- Java课程寒假之开发记账本软件(网页版)之三
- np.pad()用于卷积网络中对图片进行填充
- 网络安全之盗号木马原理
- [HAOI2012]外星人——数论欧拉函数
- Win7及以上笔记本设置共享WiFi热点
- 14个小方法巧除鞋臭脚臭