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两点间的一条路径,满足温度最大值最小,并且长度最短 输入格式 输入包含多组数据. 每 ...
随机推荐
- 剑指Offer——表示数值的字符串
题目描述: 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3. ...
- Geometric Progression---cf 567C(求组合方式,map离散)
题目链接:http://codeforces.com/contest/567/problem/C 题意就是有n个数现在要让 ai aj ak 构成公比为K的等比数列(i < j < k) ...
- docker-compose部署zk集群、kafka集群以及kafka-manager,及其遇到的问题和解决
zk集群docker-compose.yml 1.新建网络 docker network create --driver bridge --subnet --gateway 172.23.0.1 zo ...
- mysql 约束条件 auto_increment 自动增长 修改自增字段起始值
创建一张表 t20 mysql) ); Query OK, rows affected (0.01 sec) mysql> desc t20; +-------+----------+----- ...
- module_init module_exit
像你写C程序需要包含C库的头文件那样,Linux内核编程也需要包含Kernel头文件,大多的Linux驱动程序需要包含下面三个头文件:#include <linux/init.h>#inc ...
- 转载SQL_trace 和10046使用
SQL_TRACE是Oracle提供的用于进行SQL跟踪的手段,是强有力的辅助诊断工具.在日常的数据库问题诊断和解决中,SQL_TRACE是非常常用的方法.本文就SQL_TRACE的使用作简单探讨,并 ...
- 20165324 Java实验三 敏捷开发与XP实验
20165324 Java实验三 敏捷开发与XP实验 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324 指导教师:娄嘉鹏 实验日期:2018年4月16日 ...
- linux meta 18.0.1 系统安装nodejs
前置条件是:需要准备sudo apt-get 命令 第一步: 执行命令sudo apt-get install nodejs 即可安装, 之后可使用node -v 查看版本node 版本号 第二步: ...
- 【Linux学习】2.Linux常见命令行
记录学习Linux 系统的相关知识点,欢迎大家拍砖交流,一起成长:QQ:2712192471 作者背景:前端开发工程师 | Python | web安全爱好者 Linux命令行: 系统关机重启 s ...
- Javascript中的函数数学运算
1.Math函数与属性使用语法 Math.方法名(参数1,参数2,...); Math.属性; 说明 Math函数可以没有参数,比如Math.random()函数,或有多个参数,比如Math.max( ...