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两点间的一条路径,满足温度最大值最小,并且长度最短 输入格式 输入包含多组数据. 每 ...
随机推荐
- vue下使用echarts折线图及其横坐标拖拽功能
vue页面中使用折线图,并且有时间段筛选.因此就需要用到横坐标的拖拽功能. 界面效果如下: 现在来看这个效果的实现代码: drawLine() { let that = this, lineDate ...
- 剑指Offer——二叉搜索树的第k个结点
题目描述: 给定一颗二叉搜索树,请找出其中的第k大的结点. 例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4 分析: 二叉搜索树中序遍历就是从小到大.只 ...
- JMeter场景运行(非GUI方式运行命令)
JMeter场景运行方式可分为两种: GUI方式运行,视窗运行,双击jmeter.bat启动运行即可以看到运行界面: 非GUI方式运行,在命令窗口中使用java –jar命名运行: 但不管是以 ...
- Python多线程、多进程和协程的实例讲解
线程.进程和协程是什么 线程.进程和协程的详细概念解释和原理剖析不是本文的重点,本文重点讲述在Python中怎样实际使用这三种东西 参考: 进程.线程.协程之概念理解 进程(Process)是计算机中 ...
- git学习------>如何修改git已提交的记录中的Author和Email?
一.背景 最近搭建好GitLab后,准备陆陆续续的将之前在SVN仓库中保存的代码迁移到GitLab上,昨天顺利将三个Android组件的代码迁移到GitLab后,其他同事发现迁移是成功了,但是pull ...
- SpringBoot安装和创建简单的Web应用
SpringBoot安装 方式一: Eclipese->Help->Eclipse Marketplace ->Finde STS -> Install 注意:安装过程中挺慢, ...
- SSO之CAS基础及应用视频教程(1)
CAS介绍 CAS = Central Authentication Service,中央认证服务.CAS 是 Yale 大学发起的一个开源项目,能够为 Web 应用系统或者非Web应用系统提 ...
- 【开发者笔记】归并排序过程呈现之java内置GUI表示
在网上看到一个视频将各种排序用视频表示出来,配上音乐,挺好玩的样子,就算是不会编程的人看到也会觉得很舒服,碰巧我也正在写归并算法,于是就用java的GUI实现一个. 归并排序的时间复杂度是T(n)=O ...
- Ubuntu apt-get更换阿里云源
sudo vim /etc/apt/sources.list deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe ...
- Code signing is required for product type 'Application' in SDK 'iOS 11.2'
在打包的时候出现这样一个错误,Code signing is required for product type 'Application' in SDK 'iOS 11.2' ,就是说代码签名证书 ...