题目大意:

有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点。秦始皇希望这所有n-1条路长度之和最短。然后徐福突然有冒出来,说是他有魔法,可以不用人力、财力就变出其中任意一条路出来。

秦始皇希望徐福能把要修的n-1条路中最长的那条变出来,但是徐福希望能把要求的人力数量最多的那条变出来。对于每条路所需要的人力,是指这条路连接的两个城市的人数之和。

最终,秦始皇给出了一个公式,A/B,A是指要徐福用魔法变出的那条路所需人力, B是指除了徐福变出来的那条之外的所有n-2条路径长度之和,选使得A/B值最大的那条。

分析:

A/B 要最大 那么 B 就应该最小,为了使 B 最小,可以求最小生成树,去掉权值最大的边,对于找权值最大边,两重循环枚举即可,如果该边在最小生成树上,直接去掉,如果不在最小生成树上,必然会产生一个环,那么去掉这一个环上的最大边,这就是次小生成树的算法。


#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int Max = + ;
int po[Max], X[Max], Y[Max];
int T, n;
double G[Max][Max], maxlen[Max][Max];
bool used[Max], eused[Max][Max];
double mincost[Max];
int mincostfrom[Max];
double prime()
{
memset(used, , sizeof(used));
memset(eused, , sizeof(eused));
memset(maxlen, , sizeof(maxlen));
double ans = ;
mincostfrom[] = ; // 一个边有两个顶点,这个mincost[i] = j,表示 j - i 这样一条边
for (int i = ; i < n; i++)
mincost[i] = INF;
mincost[] = ;
int added = ;
while (added < n)
{
double cost = (double) INF;
int from, to;
for (int t = ; t < n; t++)
{
if (used[t] == && cost > mincost[t])
{
from = mincostfrom[t];
to = t;
cost = mincost[t];
}
}
added++;
ans += cost;
eused[from][to] = eused[to][from] = ; // 在最小生成树上
used[to] = ;
for (int i = ; i < n; i++)
{
if (used[i] && to != i)
maxlen[i][to] = maxlen[to][i] = max(maxlen[i][from], max(maxlen[i][to], G[from][to])); // maxlen[i][j] 表示 i 和 j之间权值最大边,找到一个边就要更新
}
for (int i = ; i < n; i++)
{
if (!used[i] && G[to][i] < mincost[i])
{
mincost[i] = G[to][i];
mincostfrom[i] = to;
}
}
}
return ans;
}
int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
for (int i = ; i < n; i++)
{
scanf("%d%d%d", &X[i], &Y[i], &po[i]);
}
for (int i = ; i < n; i++)
{
for (int j = i + ; j < n; j++)
{
double dis = sqrt((double) (X[j] - X[i]) * (X[j] - X[i]) + (double) (Y[j] - Y[i]) * (Y[j] - Y[i]));
G[i][j] = G[j][i] = dis;
}
}
double mst = prime();
//cout << mst << endl;
double ans = ;
for (int i = ; i < n; i++)
{
for (int j = i + ; j < n; j++)
{
double popu = po[i] + po[j];
double tollen;
if (eused[i][j])
{
tollen = mst - G[i][j];
}
else
{
tollen = mst - maxlen[i][j];
}
ans = max(ans, popu / tollen);
}
}
// cout << ans << endl;
printf("%.2f\n", ans);
}
return ;
}

HDU 4081Qin Shi Huang's National Road System(次小生成树)的更多相关文章

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

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

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

  4. HDU 4081 Qin Shi Huang's National Road System [次小生成树]

    题意: 秦始皇要建路,一共有n个城市,建n-1条路连接. 给了n个城市的坐标和每个城市的人数. 然后建n-2条正常路和n-1条魔法路,最后求A/B的最大值. A代表所建的魔法路的连接的城市的市民的人数 ...

  5. hdu4081 Qin Shi Huang's National Road System 次小生成树

    先发发牢骚:图论500题上说这题是最小生成树+DFS,网上搜题解也有人这么做.但是其实就是次小生成树.次小生成树完全当模版题.其中有一个小细节没注意,导致我几个小时一直在找错.有了模版要会用模版,然后 ...

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

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

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

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

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

随机推荐

  1. SYN Flood测试

    由于工作需要对公司进行SYN Flood测试,在网上查了些资料,Youtube上找到最多的方法就是hping3工具来实现, 该工具已经预装在Kali下,具体操作用一条命令即可实现. hping3 -S ...

  2. OC泛型

    OC泛型 泛型是程序设计语言的一种特性,他主要是为了限制类型的,比如OC中的数组,你可以限制他里面装的是NSString类型,泛型的话JAVA和C++都有的,大家要是对泛型不了解的话可以去百度一下. ...

  3. swift-分支

    swift相当于OC的比较 if后的括号可以省略 if后只能接bool值 if后的大括号不能省略 let num1 = 5.0 let num2 = 4.0 let boo :Bool = true ...

  4. 玩转Podfile

    前言 经常使用CocoaPods来管理iOS项目中的第三方库,但是我们要使用CocoaPods来管理第三方库,前提是要写好Podfile文件,通过这个文件来配置第三方库与项目之间的依赖.版本等信息. ...

  5. Action.c(58): Error -27796: Failed to connect to server "hostname"

    分析: 因为负载生成器的性能太好发数据特别快,服务器响应也特别快,从而导致负载生成器的端口在没有timeout之前就全部占满了. 解决方案一:   在负载生成器的注册表HKEY_LOCAL_MACHI ...

  6. java 中时间的比较 用compareTo方法

    //compareTo 方法  是对象比较 大于 1   等于  返0  小于  返 -1 列 Date  dat1=new Date(); Date  dat2=new Date(); int va ...

  7. Node.js 教程 05 - EventEmitter(事件监听/发射器 )

    目录: 前言 Node.js事件驱动介绍 Node.js事件 注册并发射自定义Node.js事件 EventEmitter介绍 EventEmitter常用的API error事件 继承EventEm ...

  8. T-SQL 查询数据库中各个表的使用空间

    1. 查询单表 EXEC sp_spaceused 'dbo.tablename' 2. 查询所有表 SELECT t.NAME AS TableName, s.Name AS SchemaName, ...

  9. ActiveMQ笔记(4):搭建Broker集群(cluster)

    上一篇介绍了基于Networks of Borkers的2节点HA方案,这一篇继续来折腾Networks of Brokers,当应用规模日渐增长时,2节点的broker可能仍然抗不住访问压力,这时候 ...

  10. [原]CentOS7.2最小安装环境部署Asp.NET Core笔记

    转载请注明原作者(think8848)和出处(http://think8848.cnblogs.com) 写在前面的话 不知不觉在cnblogs上注册已经10多年了,看我的园龄就直接暴露了我实际年龄, ...