题意:

秦始皇要修路使得所有的城市连起来,并且花费最少;有一个人,叫徐福,他可以修一条魔法路,不花费任何的钱与劳动力。

秦始皇想让修路的费用最少,但是徐福想要受益的人最多,所以他们经过协商,决定让 A / B 最大,A代表被魔法路连接的两个城市的人口总数,B代表修的路中非魔法路的总长度。

输出 A / B 的最大值。

思路:

A / B 最大,则A尽可能大,B尽可能小,所以首先把MST求出来。由于每个城市的人口有很大的偏差,所以必须枚举每一条边,计算连接的两个城市的人口,复杂度为O(n^2),所以每次替换边的复杂度必须是O(1)。

由于是稠密图,所以用prim算法,prim算法在O(n^2)的复杂度的时候,可以维护最小生成树上两点之间的最长边,这样就可以在过程中把两点间的最长边保存下来。这个是依靠已知的前驱节点实现的。复杂度为O(n^2)。

枚举每一条边时,如果这条边是MST中的边,那么就直接计算 A / B;如果这条边不在MST中,加入这条边就会成环,这时我们保存的信息就起作用了,成环之后把在MST中的连接这两点的最长边去掉,就是新的生成树的权值,且保证了B尽可能小。替换的时间复杂度为O(1)。

代码:

 #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std;
const int maxn = ;
double path[maxn][maxn];
double g[maxn][maxn];
double dis[maxn];
bool vis[maxn];
bool used[maxn][maxn];
int peo[maxn];
int pre[maxn];
double ans;
struct point
{
int x,y;
}p[maxn]; double cal(int i,int j)
{
double x2 = (p[i].x - p[j].x) * (p[i].x - p[j].x);
double y2 = (p[i].y - p[j].y) * (p[i].y - p[j].y); return sqrt(x2 + y2);
} int prim(int n)
{
memset(vis,,sizeof(vis));
memset(path,,sizeof(path));
memset(used,,sizeof(used));
for (int i = ;i <= n;i++) dis[i] = 1e15; vis[] = ;
dis[] = ; int tot = ;
ans = ;
//double len = 0; for (int i = ;i <= n;i++)
{
pre[i] = ;
dis[i] = g[][i];
} for (int i = ;i < n;i++)
{
int u;
double d = 1e15; for (int j = ;j <= n;j++)
{
if (!vis[j] && dis[j] < d)
{
d = dis[j];
u = j;
}
} vis[u] = ; ans += d; //tot = max(peo[u] + peo[pre[u]],tot); used[u][pre[u]] = used[pre[u]][u] = ; for (int j = ;j <= n;j++)
{
if (vis[j] && j != u)
path[u][j] = path[j][u] = max(d,path[j][pre[u]]);
} for (int j = ;j <= n;j++)
{
if (!vis[j])
{
if (g[u][j] < dis[j])
{
dis[j] = g[u][j];
pre[j] = u;
}
}
}
} //printf("%.2f **\n",ans); return tot;
} int main()
{
int t; scanf("%d",&t); while (t--)
{
int n; scanf("%d",&n); for (int i = ;i <= n;i++)
{
scanf("%d%d%d",&p[i].x,&p[i].y,&peo[i]);
} for (int i = ;i <= n;i++)
{
for (int j = ;j <= n;j++)
{
g[i][j] = 1e15;
}
} for (int i = ;i <= n;i++)
{
for (int j = i+;j <= n;j++)
{
g[i][j] = g[j][i] = cal(i,j);
}
} prim(n); double ans1 = ; for (int i = ;i <= n;i++)
{
for (int j = i + ;j <= n;j++)
{
if (used[i][j])
{
int peop = peo[i] + peo[j];
ans1 = max(peop / (ans - g[i][j]),ans1); //printf("%d %d %d %.2f **\n",i,j,peop,ans - g[i][j]);
}
else
{
int peop = peo[i] + peo[j];
ans1 = max(peop / (ans - path[i][j]),ans1);
//printf("%d %d %d %.2f **\n",i,j,peop,ans - path[i][j]);
}
}
} printf("%.2f\n",ans1); //printf("%.2f",path[1][4]);
} return ;
}

uvalive 5731 Qin Shi Huang’s National Road System的更多相关文章

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

  2. UVALive 5713 Qin Shi Huang's National Road System秦始皇修路(MST,最小瓶颈路)

    题意: 秦始皇要在n个城市之间修路,而徐福声可以用法术位秦始皇免费修1条路,每个城市还有人口数,现要求徐福声所修之路的两城市的人口数之和A尽量大,而使n个城市互通需要修的路长B尽量短,从而使得A/B最 ...

  3. UVALive 5713 Qin Shi Huang's National Road System(次小生成树)

    题意:对于已知的网络构建道路,使城市两两之间能够互相到达.其中一条道路是可以免费修建的,问需要修建的总长度B与免费修建的道路所连接的两城市的人口之和A的比值A/B最大是多少. 因为是求A/B的最大值, ...

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

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

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

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

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

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

    Qin Shi Huang's National Road System                                                                 ...

随机推荐

  1. Android SDK 环境搭建

    Android SDK(Software Development Kit,软件开发工具包)提供了 Android API 库和开发工具构建,测试和调试应用程序.简单来讲,Android SDK 可以看 ...

  2. Linux忘记密码常用的几种解决方法

    原文链接:https://www.cnblogs.com/vurtne-lu/p/6550590.html 一. lilo引导1. 在出现 lilo: 提示时键入 linux single Boot: ...

  3. java JDBC (七) org.apache.commons.dbutils 查询

    package cn.sasa.demo1; import java.sql.Connection; import java.sql.SQLException; import java.util.Li ...

  4. POJ2274 Long Long Message 字符串

    正解:SA/哈希+二分 解题报告: 传送门! 啊先放下翻译,,,?大意就有两个字符串,求这两个字符串的最长公共子串 先港SA的做法趴 就把两个子串拼接起来,然后题目就变成了求后缀的最长公共前缀了 所以 ...

  5. EXPLAIN执行计划中要重点关注哪些要素(叶金荣)

    原文:http://mp.weixin.qq.com/s/CDKN_nPcIjzA_U5-xwAE5w 导读 EXPLAIN的结果中,有哪些关键信息值得注意呢? MySQL的EXPLAIN当然和ORA ...

  6. SpringBoot-整合log4j日志记录

    新建log4j配置文件 文件名称log4j.properties #log4j.rootLogger=CONSOLE,info,error,DEBUG log4j.rootLogger=info,er ...

  7. 帝国cms如何调用指定id的文章到首页?

    小美女用帝国cms建了一个站,现在首页调出指定id为12的文章作为推荐,附带文章摘要,她想用代码的形式直接掉用,以后方便修改.那么,帝国cms如何调用指定id的文章呢?指定信息id,不是调用指定栏目i ...

  8. linux搭建PHP开发环境

    因为PHP是一门易于上手的开发语言,所以现在越来越多的初创公司选择PHP作为前期项目的主要开发语言. 工欲善其事,必先利其器! 现在我们就从最基本的环境搭建开始,PHP环境的搭建是非常简单的: 环境: ...

  9. 006-优化web请求二-应用缓存、异步调用【Future、ListenableFuture、CompletableFuture】、ETag、WebSocket【SockJS、Stomp】

    四.应用缓存 使用spring应用缓存.使用方式:使用@EnableCache注解激活Spring的缓存功能,需要创建一个CacheManager来处理缓存.如使用一个内存缓存示例 package c ...

  10. 20165236 2017-2018-2 《Java程序设计》结对编程练习_四则运算

    20165236 2017-2018-2 <Java程序设计>结对编程练习_四则运算 结对小组:叶佺.郭金涛 一.需求分析: 1.能随机生成n道四则运算题目,n由使用者输入: 2.支持多种 ...