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 求该边两顶点权值和除以 ...
随机推荐
- poj 2723
Get Luffy Out Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7295 Accepted: 2778 Des ...
- uva 11324
Problem B: The Largest Clique Given a directed graph G, consider the following transformation. First ...
- HDU 1026 Ignatius and the Princess I (BFS)
题目链接 题意 : 从(0,0)点走到(N-1,M-1)点,问最少时间. 思路 : BFS..... #include <stdio.h> #include <string.h> ...
- SQL Server Configuration Manager出错
在 Windows 桌面上,单击“开始”,然后单击“运行”. 在“打开”框中,键入 MMC,然后单击“确定”. 在“控制台”窗口中,单击菜单栏上的“文件”,然后单击“添加/删除管理单元”. 在“ ...
- C语言一些常用内存分配函数
首先看个问题程序(这里用的是TC编译器): #include "stdlib.h" #include "stdio.h" void main() { in ...
- C连接oracle(PROC*C)
1. 安装oralce 10g 2.建立数据库和用户 配置VS2005环境 proc需要嵌入式环境 在C/C++常规里面加入 D:\oracle\product\10.2.0\db_1\precom ...
- 545C. Woodcutters
题目链接 题意: n个树,在x1,x2,...,xn的位置,树的高度依次是h1,h2,...,hn 求的是当把树砍倒时候,不占用相邻树的位置,最大砍树个数 可向左 向右砍,即树向左向右倒,很显然 当树 ...
- JSTL Tag学习笔记(一)之<c: />
注:本文中的例子主要来自http://www.tutorialspoint.com/jsp/jsp_standard_tag_library.htm. ======================= ...
- 学了C语言,如何利用cURL写一个程序验证某个网址的有效性?
在<C程序设计伴侣>以及这几篇关于cURL的文章中,我们介绍了如何利用cURL写一个下载程序,从网络下载文件.可是当我们在用这个程序下载文件时,又遇到了新问题:如果这个网址是无效的,那么我 ...
- 几个Unicode新知识:扩展ANSI有很多种(256个字符),Unicode表示ANSI字符时高字节为0,Unicode不包括古代字符
都是有些模糊的概念,特别是Unicode不包括古代字符让我有点惊讶.看来Unicode只适用于大多数情况,一旦有无法表示的字符,那该怎么办呢? ANSI针对英语设计的,当处理带有音调标号(形如汉语的拼 ...