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

因为是求A/B的最大值,自然A越大,B越小越好。B的最小值是可以用最小生成树算法求解的,但是,由于免费修建一条道路,使得B值<最小生成树的权值和cnt。

于是,就要考虑究竟选择哪条边作为免费修建?只考虑生成树上的边还是全部边都要考虑?仔细想一下,就会发现任何一条边都存在这样的可能性。而A/B的值同时收A、B的影响,即B可以稍微大一点,只要A增大的倍数更大,那么A/B就会出现一个更优解。

至此,选择枚举每一条边(u,v)作为可能免费修建的边。当然,若它在最小生成树上,那么B==cnt-边权;若它不在最小生成树上,那么加上该条边相当于在树形结构上构造了一个环,那么减去环上任何一条边(当然不能是新加的这条边),又构成一棵树。当删除的是原树上u,v两点唯一路径上权值最大的一条边时,这棵树就是对应于所加的边(u,v)“次小生成树”(这里的次小不是真正的次小)。为什么一定是当前次小呢?由kruskal算法可知,这是通过贪心构造出的一棵树,新加上的边必然是环上的最大值(否则就不会是最小生成树了),而不在环上的边可以保证最小,所以通过如上构造,得到了一棵确定选择边(u,v)后的最小生成树,也是原图的一颗次小生成树(究竟是不是真的是次小,要比较完全部的“次小生成树”才能得到,并且注意次小生成树不唯一)。

用prim算法实现,记录(u,v)两两之间的路径上的最大值:每次记录即将加入生成树的点v与已加入的点之间的最大值,f[v]=max{f[u],w(u,v)},u是v的父亲。

 #include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#define clr(a,m) memset(a,m,sizeof(a))
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int MAXN=;
const double INF =1e9; struct Point{
int c;
double x,y;
}p[MAXN]; double mp[MAXN][MAXN],f[MAXN][MAXN]; double d[MAXN];
int vis[MAXN],fa[MAXN]; double prim(int n)
{
vector<int>q;
double cnt=; clr(vis,);
rep(i,,n)
d[i]=INF;
d[]=;
fa[]=;
rep(i,,n){
int x;
double m=INF;
rep(y,,n)
if(!vis[y]&&d[y]<m)
m=d[x=y];
vis[x]=true;
cnt+=mp[fa[x]][x]; int sz=q.size();
rep(j,,sz-){
f[q[j]][x]=f[x][q[j]]=max(f[q[j]][fa[x]],mp[fa[x]][x]);
}
q.push_back(x); rep(y,,n)
if(!vis[y]&&mp[x][y]<d[y]){
d[y]=mp[x][y];
fa[y]=x;
}
}
return cnt;
} void print(int n,double cnt)
{
double m=;
rep(i,,n)
rep(j,i+,n){
double s=cnt-f[i][j];
double t=p[i].c+p[j].c;
m=max(m,t/s);
}
printf("%.2f\n",m);
} int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
rep(i,,n)
scanf("%lf%lf%d",&p[i].x,&p[i].y,&p[i].c);
rep(i,,n){
mp[i][i]=;
rep(j,i+,n)
mp[i][j]=mp[j][i]=sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
}
double cnt=prim(n);
print(n,cnt);
}
return ;
}

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

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

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

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

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

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

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

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

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

  8. uvalive 5731 Qin Shi Huang’s National Road System

    题意: 秦始皇要修路使得所有的城市连起来,并且花费最少:有一个人,叫徐福,他可以修一条魔法路,不花费任何的钱与劳动力. 秦始皇想让修路的费用最少,但是徐福想要受益的人最多,所以他们经过协商,决定让 A ...

  9. LA 5713 - Qin Shi Huang's National Road System(HDU 4081) MST

    LA:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

随机推荐

  1. HDU 2121 Ice_cream’s world II 不定根最小树形图

    题目链接: 题目 Ice_cream's world II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...

  2. js函数:setInterval()/clearInterval()——js网页计时器

    一.setInterval()/clearInterval()技术学习 都是window对象的方法,可以直接使用. setInterval(function(){},1000);:每1000毫秒执行一 ...

  3. How does database indexing work?

    When data is stored on disk based storage devices, it is stored as blocks of data. These blocks are ...

  4. MYSQL存储过程中常使用的命令记录

    MYSQL存储过程中常使用的命令记录 1.触发器trigger 查看:show triggers; 2.存储过程procedure 查看:show procedure status; 查看详细:sho ...

  5. C Primer Plus之高级数据表示

     抽象数据类型(ADT)    类型是由什么组成?一个类型(type)指定两类信息:一个属性集和一个操作集. 所以您想定义一个新的数据类型.首先,您需要提供存储数据的方式,可能是通过设计一个结构.第二 ...

  6. struts2学习笔记(4)——数据类型转换

    回过头来看昨天的那个例子. 在昨天的例子中,只转换了一个Point类,如果想转换多个Point类怎么办呢?在昨天的例子上面做一个小的修改. 首先在input.jsp页面中修改几个输入框. <s: ...

  7. Java学习笔记(二)UML基础

    用例图:代表系统的一个功能模块,仅仅是系统功能的描述.用例图包括:用例.角色.角色和用例之间的关系以及系统内用例之间的关系. 类图:表示系统中包含哪些实体,各实体之间如何关联. 类图除了表示实体内部结 ...

  8. ASP.NET连接数据库并获取数据

    关键词:连接对象的用法SqlConnection,SqlCommand,SqlDataAdapter *数据访问方式的写法 工具/原料 VS SQL SERVER 2012 R2 方法/步骤1: 1. ...

  9. windows下安装ubantu

        首先声明我是一个linux大菜鸟,之所以学这个,一个是好玩,另外做DL的一些软件如Caffe要在这个平台上运行,所以没事就鼓捣鼓捣.linux是一种内核,市场上支持这种内核的操作系统有uban ...

  10. 【mysql的编程专题④】存储过程

    类似函数,但是没有返回值,把sql进行封装,便于多次使用或多种应用程序共享使用.不能用在SQL语句中,只能使用CALL调用; 创建存储过程 语法 CREATE PROCEDURE sp_name ([ ...