UVa 11354 邦德(最小瓶颈路+LCA)
https://vjudge.net/problem/UVA-11354
题意:
有n个城市m条道路,每条道路有一个危险系数。先在有若干个询问,要求找到一条从s到t的路,使得途径所有边的最大危险系数最小。
思路:
最小瓶颈路肯定是在最小生成树上的。所有先求最小生成树。
然后将它转化成有根树,让fa[i]和cost[i]分别表示结点i的父亲编号和它与父亲之间的边权L[i]表示结点i的深度。
anc[i][j]表示结点i的第2^j级祖先的编号(j==0时候就是fa[i],如果第2^j祖先不存在,设为-1)。
maxcost[i][j]表示结点i和第2^j级祖先之间路径上的最大权值。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
const int maxn=+;
const int INF=0x3f3f3f; struct node
{
int u,v,d;
bool operator < (const node& rhs) const
{
return d<rhs.d;
}
}edge[*maxn]; int n,m;
int cnt;
int p[maxn];
vector<int> g[maxn];
vector<int> c[maxn]; int find(int x)
{
return x==p[x]?x:p[x]=find(p[x]);
} struct LCA
{
int n;
int fa[maxn];
int cost[maxn];
int L[maxn];
int anc[maxn][]; //结点i的第(1<<j)级祖先编号,anc[i][0]就是父亲fa[i],anc[i][j]=-1表示该祖先不存在
int maxcost[maxn][]; //结点i和它的(1<<j)级祖先之间的路径上的最大权值 void preprocess() //预处理
{
for(int i=;i<n;i++)
{
anc[i][]=fa[i]; maxcost[i][]=cost[i];
for(int j=;(<<j)<n;j++) anc[i][j]=-;
}
for(int j=;(<<j)<n;j++)
{
for(int i=;i<n;i++)
if(anc[i][j-]!=-)
{
int a=anc[i][j-];
anc[i][j]=anc[a][j-];
maxcost[i][j]=max(maxcost[i][j-],maxcost[a][j-]);
}
}
} int query(int p,int q)
{
int tmp, log, i;
if(L[p] < L[q]) swap(p,q);
for(log=; (<<log) <= L[p]; log++); log--; int ans=-INF;
for(int i=log; i>=;i--)
if(L[p]-(<<i)>=L[q]) //让p和q处于同一层
{
ans=max(ans,maxcost[p][i]);
p=anc[p][i];
} if(p==q) return ans; //LCA为p for(int i=log;i>=;i--)
if(anc[p][i]!=-&&anc[p][i]!=anc[q][i])//否则,让p,q同时往上爬,保证爬的时候始终处于同一层
{
ans=max(ans,maxcost[p][i]);p=anc[p][i];
ans=max(ans,maxcost[q][i]);q=anc[q][i];
}
ans=max(ans,cost[p]);
ans=max(ans,cost[q]);
return ans; //LCA为fa[p](或fa[q])
}
}solver; void MST()
{
sort(edge,edge+cnt);
int num=;
for(int i=;i<cnt;i++)
{
int x=edge[i].u,y=edge[i].v;
int u=find(x),v=find(y);
if(u!=v)
{
p[u]=v;
g[x].push_back(y); c[x].push_back(edge[i].d);
g[y].push_back(x); c[y].push_back(edge[i].d);
if(++cnt==n-) break;
}
}
} void dfs(int u,int fa,int level) //无根树转有根树
{
solver.L[u]=level;
for(int i=;i<g[u].size();i++)
{
int v=g[u][i];
if(v!=fa)
{
solver.fa[v]=u;
solver.cost[v]=c[u][i]; //cost就是v点到其父亲结点的权值
dfs(v,u,level+);
}
}
} int main()
{
//freopen("D:\\input.txt","r",stdin);
int kase=;
while(~scanf("%d%d",&n,&m) && n)
{
cnt=;
for(int i=;i<n;i++) {p[i]=i;g[i].clear();c[i].clear();}
for(int i=;i<m;i++)
{
int x,y,d;
scanf("%d%d%d",&x,&y,&d);
edge[cnt].u=x-;
edge[cnt].v=y-;
edge[cnt].d=d;
cnt++;
}
MST();
dfs(,-,);
solver.n=n;
solver.preprocess();
int q;
if(kase++!=) puts("");
scanf("%d",&q);
while(q--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",solver.query(x-,y-));
}
}
return ;
}
UVa 11354 邦德(最小瓶颈路+LCA)的更多相关文章
- UVA 11354 Bond(最小瓶颈路+倍增)
题意:问图上任意两点(u,v)之间的路径上,所经过的最大边权最小为多少? 求最小瓶颈路,既是求最小生成树.因为要处理多组询问,所以需要用倍增加速. 先处理出最小生成树,prim的时间复杂度为O(n*n ...
- 最小瓶颈路 Uva 534 Frogger
说明:关于Uva的题目,可以在vjudge上做的,不用到Uva(那个极其慢的)网站去做. 最小瓶颈路:找u到v的一条路径满足最大边权值尽量小 先求最小生成树,然后u到v的路径在树上是唯一的,答案就是这 ...
- LOJ#137. 最小瓶颈路 加强版(Kruskal重构树 rmq求LCA)
题意 三倍经验哇咔咔 #137. 最小瓶颈路 加强版 #6021. 「from CommonAnts」寻找 LCR #136. 最小瓶颈路 Sol 首先可以证明,两点之间边权最大值最小的路径一定是在最 ...
- 【uva 534】Frogger(图论--最小瓶颈路 模版题)
题意:平面上有N个石头,给出坐标.一只青蛙从1号石头跳到2号石头,使路径上的最长便最短.输出这个值.(2≤N≤200) 解法:最小瓶颈树.而由于这题N比较小便可以用2种方法:1.最短路径中提到过的Fl ...
- CF600 div2 F.Cheap Robot(思维+最短路+最小瓶颈路)
最开始啃这题的时候我还是个不会$lca$的人,看代码看的没有一点头绪,现在趁着寒假补了很多关于图论的知识点,回头在看这题还是有很多值得学习的地方. Solution 1 (offline): 原题解: ...
- UVALive 5713 Qin Shi Huang's National Road System秦始皇修路(MST,最小瓶颈路)
题意: 秦始皇要在n个城市之间修路,而徐福声可以用法术位秦始皇免费修1条路,每个城市还有人口数,现要求徐福声所修之路的两城市的人口数之和A尽量大,而使n个城市互通需要修的路长B尽量短,从而使得A/B最 ...
- 【UVA534】Frogger 最小瓶颈路
题目大意:给定一张 N 个点的完全图,求 1,2 号节点之间的一条最小瓶颈路. 题解:可知,最小瓶颈路一定存在于最小生成树(最小瓶颈树)中.因此,直接跑克鲁斯卡尔算法,当 1,2 号节点在同一个联通块 ...
- 【20181102T2】飞越行星带【智商题+最小瓶颈路】
题面 [正解] 一眼不可做啊 --相当于求路线上穿过的点最小距离最大 最小最大--二分啊 现在相当于给一个直径,要判断这个直径是否能从左边穿到右边 我们可以在距离不超过直径的点连一条边,\(y=0\) ...
- 【UVA10816】Travel in Desert (最小瓶颈路+最短路)
UVA10816 Travel in Desert 题目大意 沙漠中有一些道路,每个道路有一个温度和距离,要求s,t两点间的一条路径,满足温度最大值最小,并且长度最短 输入格式 输入包含多组数据. 每 ...
随机推荐
- PHP 错误日志
display_errors 错误回显,一般常用语开发模式,但是很多应用在正式环境中也忘记了关闭此选项.错误回显可以暴露出非常多的敏感信息,为攻击者下一步攻击提供便利.推荐关闭此选项. display ...
- ledecode Reverse Words in a String III
557. Reverse Words in a String III Given a string, you need to reverse the order of characters in ea ...
- 获取当前文件夹以及子文件夹下所有文件C++
void getFiles( string path,vector<string>& files) { //文件句柄 ; //文件信息 struct _finddata_t fil ...
- oracle入门(8)——实战:支持可变长参数、多种条件、多个参数排序、分页的存储过程查询组件
[本文介绍] 学了好几天,由于项目需要,忙活了两天,写出了个小组件,不过现在还只能支持单表操作.也没考虑算法上的优化,查询速度要比hibernate只快了一点点,可能是不涉及多表查询的缘故吧,多表的情 ...
- docker部署Jenkins,以及在Jenkins中使用宿主机的docker/docker-compose命令
使用最新的官方镜像jenkins/jenkins 第一次使用的docker部署jenkins的时候,出现了两个问题: 1.因为用户权限问题挂载/home/jenkins/data到/var/jenki ...
- 八、网页版消息推送SDK-WebSockets
介绍 由于项目组需求.最近在研究消息推送服务平台.结合业务和使用场景分析最终选择的是 Mosquitto 消息服务器. Mosquitto 服务器的安装.配置.集群搭建 我就不在这多说了.有兴趣的可以 ...
- DOS命令安装配置Apache + MySQL + PHP 开发环境 (VC11)
一.下载 1.下载Apache 下载地址:https://www.apachelounge.com/download/VC11/ 2.下载MySQL 下载地址:http://dev.mysql.com ...
- 微信小程序组件action-sheet
操作反馈action-sheet:官方文档 Demo Code: Page({ data: { actionSheetHidden: true, actionSheetItems: ['item1', ...
- [笔记] Ubuntu 18.04安装Docker CE及nvidia-docker2流程
Docker的好处之一,就是在Container里面可以随意瞎搞,不用担心弄崩Host的环境. 而nvidia-docker2的好处是NVidia帮你配好了Host和Container之间的CUDA相 ...
- Leetcode 357
没用过Leetcode刷题,只能按照自己的想法随便写写了 思路:1.第一位数有9种(除了0)可能,第二位数有9种(除了第一位)可能,第三位数有8种(除了前两位)可能,以此类推...9*8*7*...( ...