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)的更多相关文章

  1. UVA 11354 Bond(最小瓶颈路+倍增)

    题意:问图上任意两点(u,v)之间的路径上,所经过的最大边权最小为多少? 求最小瓶颈路,既是求最小生成树.因为要处理多组询问,所以需要用倍增加速. 先处理出最小生成树,prim的时间复杂度为O(n*n ...

  2. 最小瓶颈路 Uva 534 Frogger

    说明:关于Uva的题目,可以在vjudge上做的,不用到Uva(那个极其慢的)网站去做. 最小瓶颈路:找u到v的一条路径满足最大边权值尽量小 先求最小生成树,然后u到v的路径在树上是唯一的,答案就是这 ...

  3. LOJ#137. 最小瓶颈路 加强版(Kruskal重构树 rmq求LCA)

    题意 三倍经验哇咔咔 #137. 最小瓶颈路 加强版 #6021. 「from CommonAnts」寻找 LCR #136. 最小瓶颈路 Sol 首先可以证明,两点之间边权最大值最小的路径一定是在最 ...

  4. 【uva 534】Frogger(图论--最小瓶颈路 模版题)

    题意:平面上有N个石头,给出坐标.一只青蛙从1号石头跳到2号石头,使路径上的最长便最短.输出这个值.(2≤N≤200) 解法:最小瓶颈树.而由于这题N比较小便可以用2种方法:1.最短路径中提到过的Fl ...

  5. CF600 div2 F.Cheap Robot(思维+最短路+最小瓶颈路)

    最开始啃这题的时候我还是个不会$lca$的人,看代码看的没有一点头绪,现在趁着寒假补了很多关于图论的知识点,回头在看这题还是有很多值得学习的地方. Solution 1 (offline): 原题解: ...

  6. UVALive 5713 Qin Shi Huang's National Road System秦始皇修路(MST,最小瓶颈路)

    题意: 秦始皇要在n个城市之间修路,而徐福声可以用法术位秦始皇免费修1条路,每个城市还有人口数,现要求徐福声所修之路的两城市的人口数之和A尽量大,而使n个城市互通需要修的路长B尽量短,从而使得A/B最 ...

  7. 【UVA534】Frogger 最小瓶颈路

    题目大意:给定一张 N 个点的完全图,求 1,2 号节点之间的一条最小瓶颈路. 题解:可知,最小瓶颈路一定存在于最小生成树(最小瓶颈树)中.因此,直接跑克鲁斯卡尔算法,当 1,2 号节点在同一个联通块 ...

  8. 【20181102T2】飞越行星带【智商题+最小瓶颈路】

    题面 [正解] 一眼不可做啊 --相当于求路线上穿过的点最小距离最大 最小最大--二分啊 现在相当于给一个直径,要判断这个直径是否能从左边穿到右边 我们可以在距离不超过直径的点连一条边,\(y=0\) ...

  9. 【UVA10816】Travel in Desert (最小瓶颈路+最短路)

    UVA10816 Travel in Desert 题目大意 沙漠中有一些道路,每个道路有一个温度和距离,要求s,t两点间的一条路径,满足温度最大值最小,并且长度最短 输入格式 输入包含多组数据. 每 ...

随机推荐

  1. echarts将折线图改为曲线图

    只要在 series中加上属性: smooth: true(true为曲线.flase为直线)

  2. Websocket - Websocket原理(握手、解密、加密)、基于Python实现简单示例

    一.Websocket原理(握手.解密.加密) WebSocket协议是基于TCP的一种新的协议.WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符.它实 ...

  3. 大量高清文字版PDF编程书籍下载

    下载地址 :http://zhaojucai.com/download.html 文件夹: 数学之美(第二版) Java编程思想(第4版) 图灵程序设计丛书:Python基础教程(第2版)(修订版) ...

  4. 启动tomcat时为tomcat指定JDK

    背景:服务器环境:JDK1.7,Tomcat8 需求: 需要在Tomcat8部署项目,该项目需要运行在JDK1.8 将Tomcat8和JDK1.8上传至服务器,然后解压在指定目录下. 为tomcat指 ...

  5. 模块讲解----shutil模块(copy、压缩、解压)

    作用与功能 主要用于文件的copy,压缩,解压 导入shuitl模块: import shutil copy方法 1.shutil.copyfileobj()  打开file1,并copy写入file ...

  6. Delphi锁定鼠标 模拟左右键 静止一会自动隐藏鼠标

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  7. The Air Jordan 4 Oreo Remastered would be re-released in 2015

    May be the Jordan 4 Oreo probably the most anticipated pair among the remastered Jordans for 2015? W ...

  8. vmware12 安装linux centos6

          内核选 2.6                                                                 中文安装选 基本系统 -> 基本, 兼 ...

  9. 字符串的partition函数

    partition函数 str1='sdga2a34'aa=str1.partition('a') print(aa) """ ('sdg', 'a', '2a34') ...

  10. 新式转型操作符[条款9] --《C++必知必会》

    在旧式转型(cast)下面隐藏着一些见不得人的.鬼鬼祟祟的东西.他们的语法形式使其在一段代码中通常很难引起人们的注意,但它们可能会搞一些可怕的破坏活动,就好比你冷不丁被一个恶棍猛击一拳似的.让我们阐明 ...