UVAlive5713 Qin Shi Huang's National Road System【次小生成树】【DP】
题目大意
给你平面上的n个点
每个点有一个权值
让你求出一个生成树
可以选择一条边不花费代价
要最大化这条边两边端点的权值/剩下n-2条边的长度之和
思路
发现发现其实端点权值其实不太好处理
那么我们就用最暴力的方式来枚举这样的一条边
但是显然剩下的部分不能直接暴力最小生成树
那么就直接在原图的最小生成树上面进行考虑
加上一条边一定需要删除一条边
这样的操作一定会删除两点对应生成树链上的最大边权
所以可以预处理生成树上两点之间的最大边权
这个可以用一个简单的树形dp来完成
算法复杂度\(n^2\)也没问题
也可以用主席树来标记永久化维护
但是查询的时候会多一个log
//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
typedef pair<int, int> pi;
typedef long long ll;
typedef double db;
#define fi first
#define se second
#define fu(a, b, c) for (int a = b; a <= c; ++a)
#define fd(a, b, c) for (int a = b; a >= c; --a)
#define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar();
if (c == '-') w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
const int M = 1e6 + 10;
const int N = 1e3 + 10;
db dis[N][N], f[N][N];
pi pos[N];
int n, m, p[N];
db getpow(int x) {
return (db)x * (db)x;
}
db getdis(pi x, pi y) {
return sqrt(getpow(x.fi - y.fi) + getpow(x.se - y.se));
}
void getdis() {
fu(i, 1, n) {
fu(j, 1, n) {
dis[i][j] = getdis(pos[i], pos[j]);
}
}
}
struct Edge {
int u, v, nxt;
bool operator < (const Edge b) const {
return dis[u][v] < dis[b.u][b.v];
}
};
struct Map {
Edge E[M << 1];
int head[N], tot, n;
void init(int pn) {
n = pn;
fu(i, 1, n) head[i] = 0;
tot = 0;
}
void addedge(int u, int v) {
E[++tot] = (Edge) {u, v, head[u]};
head[u] = tot;
}
void sortedge() {
sort(E + 1, E + tot + 1);
}
} mp, mst;
struct Union_Find {
int fa[N];
void init(int n) {
fu(i, 1, n) fa[i] = i;
}
int Find(int x) {
return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
bool Merge(int x, int y) {
int fax = Find(x), fay = Find(y);
if (fax == fay) return 0;
fa[fax] = fay;
return 1;
}
} uf;
db Kruskal() {
uf.init(n);
mst.init(n);
int cnt = 0;
db res = 0;
fu(i, 1, mp.tot) {
int u = mp.E[i].u, v = mp.E[i].v;
if (uf.Merge(u, v)) {
mst.addedge(u, v);
mst.addedge(v, u);
res += dis[u][v];
if (++cnt == n - 1) break;
}
}
return res;
}
bool mark[N];
void dfs(int u, int fa) {
mark[fa] = 1;
if (fa) {
fu(j, 1, n) if (u != j) {
f[u][j] = f[j][u] = max(f[fa][j], dis[u][fa]);
}
}
for (int i = mst.head[u]; i; i = mst.E[i].nxt) {
int v = mst.E[i].v;
if (v != fa) dfs(v, u);
}
}
void solve() {
Read(n);
fu(i, 1, n)
Read(pos[i].fi), Read(pos[i].se), Read(p[i]);
getdis();
mp.init(n);
fu(i, 1, n)
fu(j, 1, i - 1)
mp.addedge(i, j);
mp.sortedge();
db tmp = Kruskal();
fu(i, 1, n) mark[i] = 0;
dfs(1, 0);
db ans = 0;
fu(i, 1, n)
fu(j, 1, i - 1)
ans = max(ans, db(p[i] + p[j]) / (tmp - f[i][j]));
printf("%.2lf\n", ans);
}
int main() {
#ifdef dream_maker
freopen("input.txt", "r", stdin);
#endif
int T; Read(T);
while (T--) solve();
return 0;
}
UVAlive5713 Qin Shi Huang's National Road System【次小生成树】【DP】的更多相关文章
- hdu 4081 Qin Shi Huang's National Road System (次小生成树的变形)
题目:Qin Shi Huang's National Road System Qin Shi Huang's National Road System Time Limit: 2000/1000 M ...
- HDU 4081 Qin Shi Huang's National Road System 次小生成树变种
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- HDU4081 Qin Shi Huang's National Road System —— 次小生成树变形
题目链接:https://vjudge.net/problem/HDU-4081 Qin Shi Huang's National Road System Time Limit: 2000/1000 ...
- HDU 4081 Qin Shi Huang's National Road System [次小生成树]
题意: 秦始皇要建路,一共有n个城市,建n-1条路连接. 给了n个城市的坐标和每个城市的人数. 然后建n-2条正常路和n-1条魔法路,最后求A/B的最大值. A代表所建的魔法路的连接的城市的市民的人数 ...
- hdu4081 Qin Shi Huang's National Road System 次小生成树
先发发牢骚:图论500题上说这题是最小生成树+DFS,网上搜题解也有人这么做.但是其实就是次小生成树.次小生成树完全当模版题.其中有一个小细节没注意,导致我几个小时一直在找错.有了模版要会用模版,然后 ...
- UVALive-5713 Qin Shi Huang's National Road System (次小生成树)
题目大意:有n个城市,要修一些路使得任意两个城市都能连通.但是有人答应可以不计成本的帮你修一条路,为了使成本最低,你要慎重选择修哪一条路.假设其余的道路长度为B,那条别人帮忙修的道路两端城市中的总人口 ...
- hdu 4081 Qin Shi Huang's National Road System (次小生成树)
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- UValive 5713 Qin Shi Huang's National Road System
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- Qin Shi Huang's National Road System HDU - 4081(树形dp+最小生成树)
Qin Shi Huang's National Road System HDU - 4081 感觉这道题和hdu4756很像... 求最小生成树里面删去一边E1 再加一边E2 求该边两顶点权值和除以 ...
随机推荐
- SLG手游Java服务器的设计与开发——网络通信
文章版权归腾讯GAD所有,禁止匿名转载:禁止商业使用:禁止个人使用. 一.前言 上文分析了我们这款SLG的架构,本章着重讲解我们的网络通信架构,由上文的功能分析我们可以得知,游戏的所有功能基本上属于非 ...
- VS2010/MFC编程入门之十七(对话框:文件对话框)
上一讲鸡啄米介绍的是消息对话框,本节讲解文件对话框.文件对话框也是很常用的一类对话框. 文件对话框的分类 文件对话框分为打开文件对话框和保存文件对话框,相信大家在Windows系统中经常见 ...
- nats
NATS is a family of open source products that are tightly integrated but can be deployed independent ...
- 在Qt中如何编写插件,加载插件和卸载插件(转)
Qt提供了一个类QPluginLoader来加载静态库和动态库,在Qt中,Qt把动态库和静态库都看成是一个插件,使用QPluginLoader来加载和卸载这些库.由于在开发项目的过程中,要开发一套插件 ...
- c++第二十五天
p129~p131: 1.赋值运算的左侧运算对象必须是一个可修改的左值. 2.赋值运算满足右结合律. 3.赋值运算的结果是它的左侧对象,并且是一个左值. 验证: #include<iostrea ...
- 前端学习笔记之CSS文档流
先引用一段W3C的文档: 9.3 Positioning schemes In CSS 2.1, a box may be laid out according to three positionin ...
- 20145201李子璇 《网络对抗》 Web基础
1.实验后回答问题 (1)什么是表单 它在网页中主要负责数据采集功能,通过用户提交的一些数据来建立网站管理者与浏览者之间的桥梁. 两个组成部分:①HTML源代码用于描述表单(比如域,标签和浏览者在页面 ...
- 20162311 课堂测试 泛型类—Bag
课堂测试 泛型类-Bag 目录 一.题目要求 二.设计思路 三.问题和解决办法 四.代码运行截图 五.代码托管地址 六.总结 一.题目要求 题目:泛型类-Bag 返回目录 二.设计思路 自定义一个Ba ...
- shell 脚本sed替换文件中某个字符串
有些大文件,特别的大.有几百兆,甚至更大. 用文本编辑器打开十分的费劲,电脑都卡死了. 想替换其中的字符串,很麻烦. 这个时候有了shell,简直强大到爆炸! # du -h user.sql 304 ...
- C#用大石头Xcode做数据底层注意事项
1.记得添加XCode.dll 和NewLife.Core.dll 2.记得把程序的框架改为 .net Framework4