UVALive 5713 Qin Shi Huang's National Road System秦始皇修路(MST,最小瓶颈路)
题意:
秦始皇要在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,最小瓶颈路)的更多相关文章
- 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 ...
- UVALive 5713 Qin Shi Huang's National Road System(次小生成树)
题意:对于已知的网络构建道路,使城市两两之间能够互相到达.其中一条道路是可以免费修建的,问需要修建的总长度B与免费修建的道路所连接的两城市的人口之和A的比值A/B最大是多少. 因为是求A/B的最大值, ...
- 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 ...
- 【最小生成树】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 ...
- uvalive 5731 Qin Shi Huang’s National Road System
题意: 秦始皇要修路使得所有的城市连起来,并且花费最少:有一个人,叫徐福,他可以修一条魔法路,不花费任何的钱与劳动力. 秦始皇想让修路的费用最少,但是徐福想要受益的人最多,所以他们经过协商,决定让 A ...
- 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 ...
- 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 ...
- 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 ...
- Qin Shi Huang's National Road System HDU - 4081(树形dp+最小生成树)
Qin Shi Huang's National Road System HDU - 4081 感觉这道题和hdu4756很像... 求最小生成树里面删去一边E1 再加一边E2 求该边两顶点权值和除以 ...
随机推荐
- Delphi托盘类 收集
收集的两个托盘程序: 1. 托盘区就是在windows的状态栏下方显示时钟.输入法状态的地方, 要把你的程序显示在托盘区: 下面是一个托盘类,只要把下面粘贴到文本文件中,改成TrayIcon.pas, ...
- 运行时修改TimerTask的执行周期
java.util.TimerTask类的执行周期period变量的声明如下: /** * Period in milliseconds for repeating tasks. A positive ...
- (转)Fibonacci Tilings
Fibonacci numbers {Fn, n ≥ 0} satisfy the recurrence relation (1) Fn+2 = Fn+1 + Fn, along with the i ...
- C# virtual和override
本文转载来自于:http://bollaxu.iteye.com/blog/1662855 在函数的声明中,当有“virtual”修饰的时候,和没有virtual有什么区别呢?最重要的一点就是调用实例 ...
- Windows启动系统程序命令
DEVMGMT.MSC - Device Manager 设备管理器 DISKMGMT.MSC - Disk Management 磁盘管理 WindowsXP常用命令http://baike.b ...
- ExtJs布局之viewport
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...
- BZOJ 1046: [HAOI2007]上升序列 LIS -dp
1046: [HAOI2007]上升序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3438 Solved: 1171[Submit][Stat ...
- poj 1733(带权并查集+离散化)
题目链接:http://poj.org/problem?id=1733 思路:这题一看就想到要用并查集做了,不过一看数据这么大,感觉有点棘手,其实,我们仔细一想可以发现,我们需要记录的是出现过的节点到 ...
- TCP三次握手和四次挥手协议
相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不需要控制这个过程.但是对于理解TCP底层运作机制,相当有帮助. TCP三次握手 所谓三次握手( ...
- Android 核心分析 之六 IPC框架分析 Binder,Service,Service manager
IPC框架分析 Binder,Service,Service manager 我首先从宏观的角度观察Binder,Service,Service Manager,并阐述各自的概念.从Linux的概念空 ...