H. Qin Shi Huang's National Road System

Time Limit: 1000ms
Memory Limit: 32768KB

64-bit integer IO format: %I64d      Java class name: Main

 
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 解题:此题跟次小生成树没多大关系,只是涉及到最小生成树的遍历问题。解题思路就是先求出最小生成树,存储这棵树,然后再在这棵树上进行去边操作,此时的两颗树上人口数最多的两个城市人口数的和 去除以 最小生成树的值减去此边的值 后的商,求这个商最大可能是多少。 Kruskal写法
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <climits>
#include <algorithm>
#include <cmath>
#define LL long long
#define INF 0x3f3f3f
using namespace std;
const int maxv = ;
const int maxe = *;
struct arc{
int u,v;
double w;
};
int uf[maxv];
vector<int>g[maxv];
arc e[maxe],tree[maxe];
int n,px[maxv],py[maxv],val[maxv];
int maxVal,es,ads;
double Minst;
bool vis[maxv];
bool cmp(const arc &x,const arc &y){
return x.w < y.w;
}
void dfs(int u){
vis[u] = true;
if(val[u] > maxVal) maxVal = val[u];
for(int i = ; i < g[u].size(); i++){
if(!vis[g[u][i]]) dfs(g[u][i]);
}
}
int findF(int x){
if(x != uf[x])
uf[x] = findF(uf[x]);
return uf[x];
}
double dis(int i,int j){
double temp = (px[i]-px[j])*(px[i]-px[j])+(py[i]-py[j])*(py[i]-py[j]);
return sqrt(temp);
}
void kruskal(){
for(int i = ; i < es; i++){
int x = findF(e[i].u);
int y = findF(e[i].v);
if(x != y){
Minst += e[i].w;
uf[x] = y;
g[e[i].u].push_back(e[i].v);
g[e[i].v].push_back(e[i].u);
tree[ads++] = e[i];
}
}
}
int main(){
int t,i,j;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i = ; i <= n; i++){
scanf("%d%d%d",px+i,py+i,val+i);
g[i].clear();
uf[i] = i;
}
ads = es = ;
Minst = ;
for(i = ; i <= n; i++)
for(j = i+; j <= n; j++){
e[es++] = (arc){i,j,dis(i,j)};
}
sort(e,e+es,cmp);
kruskal();
double ans = ,temp;
for(i = ; i < ads; i++){
int u = tree[i].u;
int v = tree[i].v;
memset(vis,false,sizeof(vis));
vis[v] = true;
temp = maxVal = ;
dfs(u);
temp += maxVal;
memset(vis,false,sizeof(vis));
maxVal = ;
vis[u] = true;
dfs(v);
temp += maxVal;
ans = max(ans,temp/(Minst-tree[i].w));
}
printf("%.2f\n",ans);
}
return ;
}

Prim写法:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <cstdlib>
#include <string>
#include <set>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxv = ;
const int maxe = *;
struct arc{
int u,v;
double w;
}e[maxe];
int px[maxv],py[maxv],val[maxv],pre[maxv];
double d[maxv],Minst,mp[maxv][maxv];
int n,tot,mxp;
vector<int>g[maxv];
bool vis[maxv];
double dis(int i,int j){
double temp = (px[i]-px[j])*(px[i]-px[j])+(py[i]-py[j])*(py[i]-py[j]);
return sqrt(temp);
}
void prim(){
int i,j,index;
double theMin;
for(i = ; i <= n; i++){
d[i] = mp[][i];
pre[i] = ;
}
for(i = ; i < n; i++){
theMin = INF;
for(j = ; j <= n; j++){
if(d[j] > && d[j] < theMin) theMin = d[index = j];
}
e[tot++] = (arc){pre[index],index,theMin};
g[index].push_back(pre[index]);
g[pre[index]].push_back(index);
Minst += theMin;
d[index] = -;
for(j = ; j <= n; j++)
if(d[j] > && d[j] > mp[index][j]){
d[j] = mp[index][j];
pre[j] = index;
}
}
}
void dfs(int u){
vis[u] = true;
if(val[u] > mxp) mxp = val[u];
for(int i = ; i < g[u].size(); i++){
if(!vis[g[u][i]]) dfs(g[u][i]);
}
}
int main(){
int t,i,j;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i = ; i <= n; i++){
scanf("%d%d%d",px+i,py+i,val+i);
g[i].clear();
}
for(i = ; i <= n; i++){
for(j = i+; j <= n; j++)
mp[i][j] = mp[j][i] = dis(i,j);
}
Minst = ;
tot = ;
prim();
double ans = ,temp;
for(i = ; i < tot; i++){
int u = e[i].u;
int v = e[i].v;
memset(vis,false,sizeof(vis));
temp = ;
mxp = ;
vis[v] = true;
dfs(u);
temp += mxp;
memset(vis,false,sizeof(vis));
vis[u] = true;
mxp = ;
dfs(v);
temp += mxp;
ans = max(ans,temp/(Minst-e[i].w));
}
printf("%.2f\n",ans);
}
return ;
}

图论trainning-part-1 H. Qin Shi Huang's National Road System的更多相关文章

  1. [hdu P4081] Qin Shi Huang’s National Road System

    [hdu P4081] Qin Shi Huang’s National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Li ...

  2. 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 ...

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

    题目链接: Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: ...

  4. 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 ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

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

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

  9. HDU4081 Qin Shi Huang's National Road System 2017-05-10 23:16 41人阅读 评论(0) 收藏

    Qin Shi Huang's National Road System                                                                 ...

随机推荐

  1. C#入门笔记1

    C#是用于创建要运行在.NET CLR上的应用程序的语言之一,从C和C++语言演化而来,是微软专门为使用.NET平台而创建的.优点:就是彻头彻尾为.NET Framework设计语言. C#能编写什么 ...

  2. 什么是OOA/OOD

    Object Oriented Analyzing Object Oriented Design Object Oriented Programming ooa(object oriented ana ...

  3. 洛谷 P1201 [USACO1.1]贪婪的送礼者Greedy Gift Givers

    贪婪的送礼者Greedy Gift Givers 难度:☆ Code: #include <iostream> #include <cstdio> #include <c ...

  4. ios自定义日期、时间、城市选择器

    选择器,我想大家都不陌生,当需要用户去选择某些范围值内的一个固定值时,我们会采用选择器的方式.选择器可以直观的提示用户选择的值范围.统一信息的填写格式,同时也方便用户快速的进行选择,比如对于性别,正常 ...

  5. win10下vs2013为程序集新建强名称文件时“未能完成操作。拒绝访问”的解决方案

    昨日,在使用vs2013开发开发一个小工具,打算给这个小工具的源代码进行保护. 在输入完成建立强名称密钥文件时,爆出了如下错误: 一开始以为是项目所在路径的权限问题,于是给项目所在路径文件夹添加了“U ...

  6. Linux SSH无密码login

    一:ssh原理图为: 1.就是为了让两个linux机器之间使用ssh不需要用户名和密码.采用了数字签名RSA或者DSA来完成这个操作 2.模型分析 假设 A (192.168.20.59)为客户机器, ...

  7. 洛谷 P1309 瑞士轮

    题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分 ...

  8. 在Mac里给Terminal终端自定义颜色

    Mac里终端显示默认是一种颜色,太单调了. 然而我们可以自定义这些颜色显示.进入-目录,编辑文件.bash_profile, 输入如下内容: 第三行那些fxfxax看起来是不是像天书?实际上是有规律的 ...

  9. struts2默认拦截器defaultStack

    第一次使用Struts2.3.20,前台页面向后台传值,怎么总是提示值为null,查找半天原来是struts配置文件的action中忘记引入defaultStack拦截器了,所以即使Action中万事 ...

  10. WPF知识点全攻略03- XAML

    XAML 是一种声明性标记语言,XAML 是一种基于 XML 并对 XML 结构规则进行了扩展. XAML特点: 定义应用程序的界面元素 显示的声明WPF资源(样式.模板.动画等) 可扩展性(自定义U ...