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: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5428 Accepted Submission(s): 1902

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.
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.
4
1 1 20
1 2 30
200 2 80
200 1 100
3
1 1 20
1 2 30
2 2 40
70.00
题意:
给你平面上若干的点,每个点有个权值$a_i$,现在用这些点构成一棵树。存在一种操作,可以使得这棵树上的某条边的长度变为0,令这条边连接的两个点分别是$i,j$,这棵树的边权和为$B$,问你$(a_i+a_j)/B$的最小值。
题解:
看网上的做法都是求次小生成树,而我却不是这样做的。
首先使用Kruskal求出最小生成树,而后枚举两个点,将这两个点之间连接那条边,这样就构成了一个换,为了保持树的形态,必须删掉这两个点的唯一路径上最长的边。
找到这条边的方法是通过倍增来求解。
令$ancestor[u][i]$为节点$u$向上走$2^i$所能到达的节点,$maxEdge[u][i]$表示节点$u$向上走$2^i$所能碰到的最长的边,那么有以下转移:
$$ancestor[u][i]=ancestor[ancestor[u][i-1]][i-1]$$
$$maxEdge[u][i]=max(maxEdge[u][i-1],maxEdge[ancestor[u][i-1]][i-1])$$
预处理出这两个数组后,就能用类似LCA的思想求最长边了。
代码:
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#define MAX_N 1234
#define MAX_D 25
using namespace std; int father[MAX_N];
int n; int popu[MAX_N]; struct edge {
int to;
double cost; edge(int t, double c) : to(t), cost(c) { } edge() { }
}; struct road {
int from, to;
double cost; road(int f, int t, double c) : from(f), to(t), cost(c) { } road() { }
}; bool cmp(road a,road b) {
if (a.cost == b.cost)
return popu[a.from] + popu[a.to] > popu[b.from] + popu[b.to];
return a.cost < b.cost;
} road ro[MAX_N*MAX_N];
int tot=;
vector<edge> G[MAX_N];
double B; int depth[MAX_N];
int ancestor[MAX_N][];
double maxEdge[MAX_N][]; struct Point {
double x, y; Point(double xx, double yy) : x(xx), y(yy) { } Point() { } double dis(Point a) {
return sqrt((x - a.x) * (x - a.x) + (y - a.y) * (y - a.y));
}
}; Point po[MAX_N]; void init() {
for (int i = ; i <= n; i++)
father[i] = i;
for (int i = ; i <= n; i++)G[i].clear();
tot = ;
B = ;
memset(depth, , sizeof(depth));
memset(ancestor, , sizeof(ancestor));
memset(maxEdge, , sizeof(maxEdge));
} int Find(int x){
if(x==father[x])return x;
return father[x]=Find(father[x]);
} void unionSet(int x,int y) {
int u = Find(x), v = Find(y);
if (u == v)return;
father[u] = v;
} bool Same(int x,int y){
return Find(x)==Find(y);
} void Kruskal() {
sort(ro + , ro + tot + , cmp);
for (int i = ; i <= tot; i++) {
int u = ro[i].from, v = ro[i].to;
if (Same(u, v))continue;
unionSet(u, v);
G[u].push_back(edge(v,ro[i].cost));
G[v].push_back(edge(u,ro[i].cost));
B += ro[i].cost;
}
} void dfs(int u,int p) {
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i].to;
double c = G[u][i].cost;
if (v == p)continue;
depth[v] = depth[u] + ;
ancestor[v][] = u;
maxEdge[v][] = c;
dfs(v, u);
}
} void getAncestor() {
for (int j = ; j < MAX_D; j++) {
for (int i = ; i <= n; i++) {
ancestor[i][j] = ancestor[ancestor[i][j - ]][j - ];
maxEdge[i][j] = max(maxEdge[i][j - ], maxEdge[ancestor[i][j - ]][j - ]);
}
}
} double LCA(int u,int v) {
double res = -;
if (depth[u] < depth[v])swap(u, v);
for (int i = MAX_D - ; i >= ; i--) {
if (depth[ancestor[u][i]] >= depth[v]) {
res = max(res, maxEdge[u][i]);
u = ancestor[u][i];
if (depth[u] == depth[v])break;
}
}
if (u == v)return res;
for (int i = MAX_D - ; i >= ; i--) {
if (ancestor[u][i] != ancestor[v][i]) {
res = max(res, max(maxEdge[u][i], maxEdge[v][i]));
u = ancestor[u][i];
v = ancestor[v][i];
}
}
return max(res, max(maxEdge[u][], maxEdge[v][]));
} int T; int main() {
cin.sync_with_stdio(false);
cin >> T;
while (T--) {
cin >> n;
init();
for (int i = ; i <= n; i++)
cin >> po[i].x >> po[i].y >> popu[i];
for (int i = ; i <= n; i++)
for (int j = i + ; j <= n; j++)
ro[++tot] = road(i, j, po[i].dis(po[j]));
Kruskal();
depth[] = ;
dfs(, );
getAncestor();
double ans = -;
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
ans = max(ans, (popu[i] + popu[j]) / (B - LCA(i, j)));
cout << setprecision() << fixed << ans << endl;
}
return ;
}
PS:第一次写手写倍增,居然一发就AC了
HDU 4081 Qin Shi Huang's National Road System 最小生成树+倍增求LCA的更多相关文章
- HDU 4081 Qin Shi Huang's National Road System 最小生成树
分析:http://www.cnblogs.com/wally/archive/2013/02/04/2892194.html 这个题就是多一个限制,就是求包含每条边的最小生成树,这个求出原始最小生成 ...
- 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 ...
- 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 ...
- 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——————【次小生成树、prim】
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- hdu 4081 Qin Shi Huang's National Road System 树的基本性质 or 次小生成树思想 难度:1
During the Warring States Period of ancient China(476 BC to 221 BC), there were seven kingdoms in Ch ...
- HDU - 4081 Qin Shi Huang's National Road System 【次小生成树】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4081 题意 给出n个城市的坐标 以及 每个城市里面有多少人 秦始皇想造路 让每个城市都连通 (直接或者 ...
- hdu 4081 Qin Shi Huang's National Road System(次小生成树prim)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 题意:有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点. ...
- HDU 4081 Qin Shi Huang's National Road System [次小生成树]
题意: 秦始皇要建路,一共有n个城市,建n-1条路连接. 给了n个城市的坐标和每个城市的人数. 然后建n-2条正常路和n-1条魔法路,最后求A/B的最大值. A代表所建的魔法路的连接的城市的市民的人数 ...
随机推荐
- (转)webView清除缓存
NSURLCache * cache = [NSURLCache sharedURLCache]; [cache removeAllCachedResponses]; [cache setDiskCa ...
- Leetcode(204) Count Primes
题目 Description: Count the number of prime numbers less than a non-negative number, n. Credits: Speci ...
- Aizu - 1378 Secret of Chocolate Poles (DP)
你有三种盘子,黑薄,白薄,黑厚. 薄的盘子占1,厚的盘子占k. 有一个高度为L的桶,盘子总高度不能超出桶的总高度(可以小于等于).相同颜色的盘子不能挨着放. 问桶内装盘子的方案数. 如 L = 5,k ...
- 十分钟了解socket
socket通讯方式------socket是TCP/IP协议的网络数据通讯接口(一种底层的通讯的方式).socket是IP地址和端口号的组合.例如:192.168.1.100:8080 原理就是TC ...
- 对于运用git将本地文件上传到coding总结
首先需要在你的本地磁盘下建立一个目录,并且进入该目录. 前几次课程上有讲到&的用法,&&表示并且. 命令 ”makir 文件名 && cd 文件名”,cd指进入 ...
- Concept with HTTP API && RPC
RPC=Remote Produce Call 是一种技术的概念名词. HTTP是一种协议,RPC可以通过HTTP来实现,也可以通过Socket自己实现一套协议来实现.所以楼主可以换一个问法,为何RP ...
- spring AOP详解三
CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的结束拦截所有父类方法的调用,并顺势织入横切逻辑.我们采用CGLib技术可以编写一个可以为任何类创建织入横切逻辑代理对象 ...
- 通过FEDERATED存储引擎同步两实例间的表数据
需求情景:实例1中A库中的三个视图是实例2中的B库所依赖的,B需要A库中三个视图的实时数据. 方案:通过FEDERATED来完成跨势力的查询FEDERATED存储引擎表只会创建表结构,不会存储表数据, ...
- Linux 终端操作之「I/O Redirection」
I/O 重定向是在终端运行程序时很常用的技巧,但是我对它所知甚少.今天我在 DigitalOcean 上发现了一篇很好的 tutorial.这篇随笔记录一下我的心得体会和发现的一个问题. I/O re ...
- HDU——1257最少拦截系统(贪心)
最少拦截系统 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...