题意:

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

思路:

  老徐可免费修得1条路,那么剩下最多也只需要修n-2条路了,这n-2条路要尽量挑短的,而老徐的那条无所谓长短,只要两城人口尽量多即可。这是没有什么贪心策略的,因为老徐所修之路会影响MST的权值之和的大小。穷举所有城市对要O(n*n),再求次MST需要O(n*n),不可行。

  换个思路,如果能先求得MST,然后穷举要老徐所要修的路,那么在加上老徐的路之后,必然会有个环的出现,这个环中有一条边是不需要的,当然不是老徐那条。这只需要在原MST中求这个环的最小瓶颈路就行了,将其删掉,加上老徐的路,构成新的MST了,进行求值。穷举老徐所要修的路也要O(n*n),那么求瓶颈路就只能用O(1)了。这可以预处理出任意城市对之间的最小瓶颈路,O(n*n)而已。

  任意点对的最小瓶颈路的求法:对原图求最小生成树,只留下树边,树中任意点对之间的路径就是该点对的最小瓶颈路。接着对树图进行DFS,在DFS过程中,顺便求出任意点对的最小瓶颈路,考虑求当前节点x到其他点的最小瓶颈路,设其父亲far,那么x可以通过far到达前面已经访问过的节点,为maxcost[已访问过的节点][far]与cost[far][x]其中的大者。按此思路,在DFS过程中可以求出任意点对的最小瓶颈路。

 #include <bits/stdc++.h>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL long long
using namespace std;
const int N=;
int a[N], b[N], seq[N]; //求MST用的
int x[N], y[N], p[N]; //所给的坐标及人口数
int pre[N], vis[N], used[N]; //求任意点对最小瓶颈路用的
double w[N], maxcost[][]; //两点间的最小瓶颈maxcost
vector<int> vect[N]; //建树时用
vector<int> dfn; //记录访问过的节点 int cmp(int a,int b){return w[a]<w[b];}
int find(int x){return pre[x]==x? x: pre[x]=find(pre[x]);} //并查集
double dis(int a,int b){return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));} void DFS(int x)
{
dfn.push_back(x); //访问过
vis[x]=;
for(int i=; i<vect[x].size(); i++)
{
int t=vect[x][i];
if(!vis[t] )
{
for(int j=; j<dfn.size(); j++) //对于所有已经访问过的节点
{
int from=dfn[j];
maxcost[t][from]=maxcost[from][t]=max(maxcost[from][x], dis(x, t) );//通过x连到t
}
DFS(t);
}
}
} void init(int n) //一堆初始化。
{
dfn.clear();
for(int i=; i<=n; i++) vect[i].clear(),pre[i]=i;
for(int i=; i<=n; i++)
for(int j=; j<=n; j++)
maxcost[i][j]=0.0;
memset(used, , sizeof(used));
memset(vis, , sizeof(vis));
}
double cal(int n, int m)
{
init(n);
double sum=0.0; //MST
for(int i=; i<m; i++) //kruscal求最小生成树
{
int u=find(a[seq[i]]);
int v=find(b[seq[i]]);
if( u!=v )
{
pre[u]=v; //不是同个连通块,则连接。
vect[a[seq[i]]].push_back( b[seq[i]] ); //顺便建图,方便建树
vect[b[seq[i]]].push_back( a[seq[i]] );
used[seq[i]]=;
sum+=w[seq[i]];
}
} DFS(); //求任意点对间的最小瓶颈路
double ans=0.0;
for(int i=; i<m; i++) //穷举徐福声将要建的边。
{
double A=p[a[i]]+p[b[i]], B; if(used[i]) B=sum-w[i]; //树上的边
else B=sum-maxcost[a[i]][b[i]];
ans=max( A/B, ans );
}
return ans;
} int main()
{
freopen("input.txt", "r", stdin);
int t, n;
cin>>t;
while(t--)
{
cin>>n;
for(int i=; i<=n; i++) scanf("%d%d%d",&x[i],&y[i],&p[i]);
int cnt=;
for(int i=; i<=n; i++) //求两点间的距离,共n*(n-1)/2条边
{
for(int j=i+; j<=n; j++)
{
a[cnt]=i;
b[cnt]=j;
w[cnt]=dis(i,j);
seq[cnt]=cnt; //千万不要用seq[cnt]=cnt++;或者seq[cnt++]=cnt。
cnt++;
}
}
sort(seq, seq+cnt, cmp); //按边长排序
printf("%.2f\n", cal(n, cnt));
} return ;
}

AC代码

UVALive 5713 Qin Shi Huang's National Road System秦始皇修路(MST,最小瓶颈路)的更多相关文章

  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(次小生成树)

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

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

  4. 【最小生成树】UVA1494Qin Shi Huang's National Road System秦始皇修路

    Description During the Warring States Period of ancient China(476 BC to 221 BC), there were seven ki ...

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

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

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

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

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

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

随机推荐

  1. Java开发WebService的几种方法--转载

    webservice的应用已经越来越广泛了,下面介绍几种在Java体系中开发webservice的方式,相当于做个记录. 1.Axis2 Axis是apache下一个开源的webservice开发组件 ...

  2. MJRefresh插件引起的错误

    添加的头部或者尾部刷新,离开这个界面的时候需要移除 - (void)dealloc {    [_tableView removeHeader];} 不同版本的处理的方式不同 报的错误: 类的一个实例 ...

  3. SQL技术内幕-8 使用WITH AS提高性能简化嵌套SQL

    --本文来源:http://www.cnblogs.com/fygh/archive/2011/08/31/2160266.html 一.WITH AS的含义 WITH AS短语,也叫做子查询部分(s ...

  4. 传说中的WCF(4):发送和接收SOAP头

    如果你实在不明白Header是个啥玩意儿,你就想一想你发送电子邮件时,是不是有个叫“附件”的东东?对啊,那么SOAP头是不是可以理解为一种附加信息?就是附加到消息正文的内容. 消息正文又是啥?WCF除 ...

  5. Windows PAE 寻址

    PAE 就是物理地址扩展.我们常规的寻址方式是之前的将虚拟地址化为10 10 12的方式来寻址页目录,页表,页偏移,但是在开始PAE之后的寻址方式发生了改变,将32位的虚拟地址转化成 2 9 9 12 ...

  6. eclipse引入tomcat

    1.默认大家的tomcat都已经安装好了,这里打开eclipse,选择windows,下面的属性(preference). 2.进入到属性配置页,选择server  --   runtime Envi ...

  7. 唉,还是Windows好

    作为一个计算机专业的,常常抱怨Windows慢.一个系统用一段时间慢下来就重装,但是次次重装很麻烦,每次重装之后还得装软件. 另外,Windows比Linux占资源,所以前段时间就想以Linux为主要 ...

  8. 程序空间(Program memory)

    The computer program memory is organized into the following: Data Segment (Data + BSS + Heap) Stack ...

  9. java web线程池

    线程池 要知道在计算机中任何资源的创建,包括线程,都需要消耗系统资源的.在WEB服务中,对于web服 务器的响应速度必须要尽可能的快,这就容不得每次在用户提交请求按钮后,再创建线程提供服务 .为了减少 ...

  10. java 基本数据类型 回顾