Qin Shi Huang's National Road System

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6137    Accepted Submission(s): 2143

Problem Description
During the Warring States Period of ancient China(476 BC to 221 BC), there were seven kingdoms in China ---- they were Qi, Chu, Yan, Han, Zhao, Wei and Qin. Ying Zheng was the king of the kingdom Qin. Through 9 years of wars, he finally conquered all six other kingdoms and became the first emperor of a unified China in 221 BC. That was Qin dynasty ---- the first imperial dynasty of China(not to be confused with the Qing Dynasty, the last dynasty of China). So Ying Zheng named himself "Qin Shi Huang" because "Shi Huang" means "the first emperor" in Chinese.

Qin Shi Huang undertook gigantic projects, including the first version of the Great Wall of China, the now famous city-sized mausoleum guarded by a life-sized Terracotta Army, and a massive national road system. There is a story about the road system:
There were n cities in China and Qin Shi Huang wanted them all be connected by n-1 roads, in order that he could go to every city from the capital city Xianyang.
Although Qin Shi Huang was a tyrant, he wanted the total length of all roads to be minimum,so that the road system may not cost too many people's life. A daoshi (some kind of monk) named Xu Fu told Qin Shi Huang that he could build a road by magic and that magic road would cost no money and no labor. But Xu Fu could only build ONE magic road for Qin Shi Huang. So Qin Shi Huang had to decide where to build the magic road. Qin Shi Huang wanted the total length of all none magic roads to be as small as possible, but Xu Fu wanted the magic road to benefit as many people as possible ---- So Qin Shi Huang decided that the value of A/B (the ratio of A to B) must be the maximum, which A is the total population of the two cites connected by the magic road, and B is the total length of none magic roads.
Would you help Qin Shi Huang?
A city can be considered as a point, and a road can be considered as a line segment connecting two points.
 
Input
The first line contains an integer t meaning that there are t test cases(t <= 10).
For each test case:
The first line is an integer n meaning that there are n cities(2 < n <= 1000).
Then n lines follow. Each line contains three integers X, Y and P ( 0 <= X, Y <= 1000, 0 < P < 100000). (X, Y) is the coordinate of a city and P is the population of that city.
It is guaranteed that each city has a distinct location.
 
Output
For each test case, print a line indicating the above mentioned maximum ratio A/B. The result should be rounded to 2 digits after decimal point.
 
Sample Input
2
4
1 1 20
1 2 30
200 2 80
200 1 100
3
1 1 20
1 2 30
2 2 40
 
Sample Output
65.00
70.00
 
Source

题意:给你n个点的坐标和每个城市的人数p,现在要修路,两点之间距离就是欧拉距离,要使得所有的n个城市都联通,且可以免费修一条路(u,v),求使得A =pu + pv,  B = 要修的其他路的总长度,  求A/B的最大值

因为要使得n个城市联通,那我们只需要修n-1条路,可以枚举免费修的路(u,v),只需要得出:包含边(u,v)的最小生成树mst(u,v)

如何得出包含边(u,v)的最小生成树呢?

我们先求一次原图的最小生成树MST,在该生成树上添加边(u,v),就会形成一个环,我们要做的就是在树中去掉u到v唯一路径上的最大边权

如何求出u到v唯一路径上的最大边呢?

mc[u][v]表示节点u到v路径上的最大边,用数组记录访问过的节点x, 有mc[v][x] = max(mc[v][u], mc[u][x])  其中u是v的父亲

在CF上有一题就是求包含每一条边的最小生成树,我们也可以在原图的最小生成树上用LCA预处理出fa[u][i]表示节点u到其第2^i个祖先的路径上的最大边权,每次可以log得出u到v的最大边

#include <bits/stdc++.h>
using namespace std;
const int N = ;
struct Edge {
int u, v;
double w;
Edge() {}
Edge(int u, int v, double w):u(u),v(v),w(w) {}
friend bool operator < (Edge a, Edge b) {
return a.w < b.w;
}
};
Edge e[N * N * ];
int x[N], y[N], fa[N];
int p[N];
vector<Edge> g[N];
double dist(int i, int j) {
return sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) * 1.0);
}
int findx(int x) {
return fa[x] == x ? x:fa[x] = findx(fa[x]);
}
double MST(int m, int n) {
for(int i = ; i < n; ++i) fa[i] = i;
sort(e, e + m);
double ans = ;
int num = ;
for(int i = ; i < m; ++i)
{
int fu = findx(e[i].u);
int fv = findx(e[i].v);
if(fu == fv) continue;
num++;
fa[fu] = fv;
ans += e[i].w;
g[e[i].u].push_back(Edge(-,e[i].v, e[i].w));
g[e[i].v].push_back(Edge(-,e[i].u, e[i].w));
if(num == n - ) break;
}
return ans;
}
double mc[N][N];
int vis[N], cur[N], c;
void DFS(int u) {
vis[u] = ; cur[c++] = u;
int sx = g[u].size();
for(int i = ; i < sx; ++i) {
int v = g[u][i].v;
double w = g[u][i].w;
if(vis[v]) continue;
for(int j = ; j < c; ++j) {
int x = cur[j];
mc[v][x] = mc[x][v] = max(w, mc[x][u]);
}
DFS(v);
}
}
double solve(int n, double B) {
double ans = ;
for(int i = ; i < n; ++i) {
for(int j = i + ; j < n; ++j)
ans = max(ans, (p[i] + p[j]) * 1.0 / (B - mc[i][j]));
}
return ans;
}
int main()
{
int _; scanf("%d", &_);
while(_ --) {
int n; scanf("%d", &n);
for(int i = ; i < n; ++i) g[i].clear();
for(int i = ; i < n; ++i) scanf("%d%d%d", &x[i], &y[i], &p[i]);
int m = ;
for(int i = ; i < n; ++i)
for(int j = i + ; j < n; ++j) {
e[m++] = Edge(i, j, dist(i, j));
}
// for(int i = 0; i < m; ++i) printf("%d %d %f\n", e[i].u, e[i].v, e[i].w);
c = ;
memset(mc, , sizeof mc);
memset(vis, , sizeof vis);
double res = MST(m, n);
DFS();
printf("%.2f\n", solve(n, res));
}
return ;
}

Hdu 4081 最小生成树的更多相关文章

  1. hdu 4081 最小生成树+树形dp

    思路:直接先求一下最小生成树,然后用树形dp来求最优值.也就是两遍dfs. #include<iostream> #include<algorithm> #include< ...

  2. hdu 4081 最小生成树变形

    /*关于最小生成树的等效边,就是讲两个相同的集合连接在一起 先建立一个任意最小生成树,这条边分开的两个子树的节点最大的一个和为A,sum为最小生成树的权值和,B为sum-当前边的权值 不断枚举最小生成 ...

  3. Qin Shi Huang's National Road System HDU - 4081(树形dp+最小生成树)

    Qin Shi Huang's National Road System HDU - 4081 感觉这道题和hdu4756很像... 求最小生成树里面删去一边E1 再加一边E2 求该边两顶点权值和除以 ...

  4. HDU 1233(最小生成树)

    HDU 1233(最小生成树 模板) #include <iostream> #include <algorithm> #include <cstdio> usin ...

  5. HDU 4081 Qin Shi Huang's National Road System 最小生成树+倍增求LCA

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 Qin Shi Huang's National Road System Time Limit: ...

  6. hdu 4081 Qin Shi Huang's National Road System(最小生成树+dp)2011 Asia Beijing Regional Contest

    同样是看别人题解才明白的 题目大意—— 话说秦始皇统一六国之后,打算修路.他要用n-1条路,将n个城市连接起来,并且使这n-1条路的距离之和最短.最小生成树是不是?不对,还有呢.接着,一个自称徐福的游 ...

  7. HDU 4081 Qin Shi Huang's National Road System 最小生成树

    分析:http://www.cnblogs.com/wally/archive/2013/02/04/2892194.html 这个题就是多一个限制,就是求包含每条边的最小生成树,这个求出原始最小生成 ...

  8. HDU 4081 Qin Shi Huang&#39;s National Road System(最小生成树/次小生成树)

    题目链接:传送门 题意: 有n坐城市,知道每坐城市的坐标和人口.如今要在全部城市之间修路,保证每一个城市都能相连,而且保证A/B 最大.全部路径的花费和最小,A是某条路i两端城市人口的和,B表示除路i ...

  9. HDU 4081 Peach Blossom Spring (最小生成树+dfs)

    题意:给定一个 n 个点和相应的权值,要求你用 n-1 条边连接起来,其中一条边是魔法边,不用任何费用,其他的边是长度,求该魔法边的两端的权值与其他边费用的尽量大. 析:先求出最小生成树,然后再枚举每 ...

随机推荐

  1. 亿级 Web 系统的容错性建设实践

    一. 重试机制 最容易也最简单被人想到的容错方式,当然就是“失败重试”,总而言之,简单粗暴!简单是指它的实现通常很简单,粗暴则是指使用不当,很可能会带来系统“雪崩”的风险,因为重试意味着对后端服务的双 ...

  2. Linux下FTP安装与配置

    第一部分 .note-content {font-family: 'Helvetica Neue', Arial, 'Hiragino Sans GB', STHeiti, 'Microsoft Ya ...

  3. iOS-不用网线搭建IPv6网络测试环境

    前言 从6月1日开始苹果要求之后审核的项目必须支持iPv6,如果不支持将被拒绝,掘金最近一次审核被就被拒绝了....理由为下: Apps are reviewed on an IPv6 network ...

  4. rails

    http://ruby-toolbox.com/ ~/.gemrc --- :backtrace: false :benchmark: false :bulk_threshold: 1000 :sou ...

  5. NAT穿越

    1.NAT类型 目前主要的NAT类型有如下几种: 1)Full-cone NAT, also known as one-to-one NAT 一旦一个内网地址 (iAddr:iPort) 被映射到一个 ...

  6. C++内存动态分配

    https://www.percona.com/blog/2012/07/05/impact-of-memory-allocators-on-mysql-performance/ https://su ...

  7. css之div等继承问题--待续

    div哪些属性是可以继承的呢? 亲测:float可以继承(错的,见下解答,),display不可以继承.有待继续学习. float不可以继承, 简单来说:浮动的元素,顾名思义,就是这个元素“浮起来”了 ...

  8. 如何在网页中添加“QQ交流”

    今天在撸码时,想到这个问题,有些网页中会有诸如,那么如何在网页添加"QQ交谈"? 第一步.登录QQ: 第二步.打开网页:QQ推广,启用QQ通讯组件: 第三步.选择组件样式,设置提示 ...

  9. [Python] 机器学习库资料汇总

    声明:以下内容转载自平行宇宙. Python在科学计算领域,有两个重要的扩展模块:Numpy和Scipy.其中Numpy是一个用python实现的科学计算包.包括: 一个强大的N维数组对象Array: ...

  10. App提交iTunes Connect,"二进制无效"问题解决方案。

    昨天提交打包提交App,将包上传到iTunes Connect之后,以为就能发布了,便点击构建版本,发现没有刚刚上传的包,于是就点击"预发行"看一下,会看到"已上传&qu ...