题意:

邦德在逃命!他在一个有N个城市,由M条边连接的道路网中。一条路的危险度被定义为这条路上危险度最大的边的危险度。

现在给出若干个询问,s,t,问从s到t的最小的危险度是多少。

思路:

首先可以证明这条路是固定的,就是最小生成树,证明略。

之后就是计算生成树上两点间的最长边,用prim算法预处理的话,由于N的规模较大,所以会超时。

由于MST是一棵树,想到树上两点之间的距离有O(log(n))的求法,即倍增求lca,按照同样的处理方法,只不过维护最大值,就可以在O(log(n))的时间内求出两点之间的最长边,查询为Q,总复杂度Qlog(n)。

代码:

 #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std; const int maxn = ;
//const int inf = 0x3f3f3f3f; struct edge
{
int fr,to,len; edge(int a,int b,int c)
{
fr = a;
to = b;
len = c;
}
}; bool cmp(edge x,edge y)
{
return x.len < y.len;
} vector<edge> g[maxn],es;
int p[maxn][];
int fa[maxn];
int par[maxn];
bool vis[maxn];
int md[maxn][];
int deep[maxn]; int fin(int x)
{
if (x == par[x]) return x;
else return par[x] = fin(par[x]);
} void unit(int x,int y)
{
x = fin(x);
y = fin(y); if (x == y) return; par[x] = y;
} void dfs(int u)
{
vis[u] = ; for (int i = ;i < g[u].size();i++)
{
edge e = g[u][i]; int to = e.to; if (vis[to]) continue; fa[to] = u; deep[to] = deep[u] + ; md[to][] = e.len; dfs(to);
}
} void pre_deal(int n)
{
for (int i = ;i <= n;i++)
{
p[i][] = fa[i];
} //int sz = (int)(log(n*1.0) / log(2.0)) + 1; for (int j = ;j<= ;j++)
{
for (int i = ;i <= n;i++)
{
p[i][j] = p[p[i][j-]][j-];
md[i][j] = max(md[i][j-],md[p[i][j-]][j-]);
}
}
} int query(int a,int b,int n)
{
if (deep[a] < deep[b]) swap(a,b); int c = deep[a] - deep[b]; int ans = ; //int sz = (int)(log(n * 1.0) / log(2.0)) + 1; for (int i = ;i <= ;i++)
{
if (c & ( << i))
{
ans = max(ans,md[a][i]);
a = p[a][i];
//printf("%d **\n",ans);
}
} if (a == b) return ans;
else
{
for (int i = ;i >= ;i--)
{
if (p[a][i] != p[b][i])
{
ans = max(ans,md[a][i]);
ans = max(ans,md[b][i]); a = p[a][i];
b = p[b][i];
}
}
} ans = max(ans,md[a][]);
ans = max(ans,md[b][]); return ans;
} void init(int n)
{
for (int i = ;i <= n;i++)
{
g[i].clear();
par[i] = i;
} es.clear(); memset(vis,,sizeof(vis));
memset(md,,sizeof(md));
memset(deep,,sizeof(deep));
memset(md,,sizeof(md));
} int main()
{
int n,m; int kase = ; while (scanf("%d%d",&n,&m) != EOF)
{
if (kase++) printf("\n"); init(n); for (int i = ;i < m;i++)
{
int a,b,c; scanf("%d%d%d",&a,&b,&c); es.push_back(edge(a,b,c));
} sort(es.begin(),es.end(),cmp); for (int i = ;i < m;i++)
{
int x = es[i].fr,y = es[i].to; if (fin(x) == fin(y)) continue; unit(x,y); g[x].push_back(edge(x,y,es[i].len));
g[y].push_back(edge(y,x,es[i].len));
} deep[] = ;
//
dfs();
//printf("233\n");
pre_deal(n); int q; scanf("%d",&q); for (int i = ;i < q;i++)
{
int a,b; int ans = ; scanf("%d%d",&a,&b); ans = query(a,b,n); printf("%d\n",ans);
}
} return ;
}

uva 11354 Bond的更多相关文章

  1. uva 11354 - Bond(树链拆分)

    题目链接:uva 11354 - Bond 题目大意:给定一张图.每次询问两个节点路径上进过边的危急值的最大值的最小值. 解题思路:首先建立最小生成数,然后依据这棵树做树链剖分. #include & ...

  2. UVA 11354 Bond 邦德 (RMQ,最小瓶颈MST)

    题意: n个城市,m条路,每条路有个危险值,要使得从s走到t的危险值最小.回答q个询问,每个询问有s和t,要求输出从s到t最小的危险值.(5万个点,10万条边) 思路: 其实要求的是任意点对之间的最小 ...

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

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

  4. UVA 11354 Bond(MST + LCA)

    n<=50000, m<=100000的无向图,对于Q<=50000个询问,每次求q->p的瓶颈路. 其实求瓶颈路数组maxcost[u][v]有用邻接矩阵prim的方法.但是 ...

  5. UVA 11354 - Bond (最小生成树 + 树链剖分)

    题目链接~~> 做题感悟:这题開始看到时感觉不是树不优点理,一想能够用 Kruskal 处理成树 ,然后就好攻克了. 解题思路: 先用 Kruskal 处理出最小生成树.然后用树链剖分 + 线段 ...

  6. UVA 11354 Bond 最小生成树 + lca

    题意 给出一张图,q个询问,每次询问给出uv,找出一条路径,使这条路径上的最大边权是两点所有路径中最小,输出这个值 思路 很显然要先求出最小生成树,任意两点在最小生成树上有唯一路径,并且这条路径上的最 ...

  7. UVA - 11354 Bond(最小生成树+LCA+瓶颈路)

    题意:N个点,M条路,每条路的危险度为路上各段中最大的危险度.多组询问,点s到点t的所有路径中最小的危险度. 分析: 1.首先建个最小生成树,则s到t的路径一定是危险度最小的. 原因:建最小生成树的最 ...

  8. 训练指南 UVA - 11354(最小生成树 + 倍增LCA)

    layout: post title: 训练指南 UVA - 11354(最小生成树 + 倍增LCA) author: "luowentaoaa" catalog: true ma ...

  9. Bond UVA - 11354(LCA应用题)

    Once again, James Bond is on his way to saving the world. Bond's latest mission requires him to trav ...

随机推荐

  1. sql生成数据库的序列号

    -- ============================================= -- Author: <Author,yaoyao,Name> -- Create dat ...

  2. block详解

    Objective-C 中 Block 有三种类型: NSStackBlock 存储于栈区 NSGlobalBlock 存储于程序数据区 NSMallocBlock 存储于堆区 block 内部没有引 ...

  3. python-面向对象-13_文件

    文件 目标 文件的概念 文件的基本操作 文件/文件夹的常用操作 文本文件的编码方式 01. 文件的概念 1.1 文件的概念和作用 计算机的 文件,就是存储在某种 长期储存设备 上的一段 数据 长期存储 ...

  4. 20170929 微信小程序项目开发

    1. 微信小程序环境搭建 请参考官网,哈哈! 2. 微信小程序基础学习 文件结构: 3. 微信小程序实战 4. 目前的逻辑,是从微信小程序的界面和服务器的Web API 进行交互, 有个注意事项就是W ...

  5. Python3学习之路~4.2 迭代器

    可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的generator fun ...

  6. 3 jmeter的两种录制方法

    录制1-badboy(推荐) badboy是一款自动化测试工具,它可以完成简单的功能测试和性能测试.其实它是一款独立的测试工具,只不过它录制东西导出的格式适用于jmeter,所以我们经常把jmeter ...

  7. 设置td中的table置顶

    style="vertical-align: top" <td colspan="11" rowspan="5" style=&quo ...

  8. vue/cli 3.0 脚手架【进阶】 使用 amfe-flexible 和 postcss-px2rem进行移动端适

    安装vue-cli3   npm install -g @vue/cli 创建项目 vue-cli-test 脚手架-项目-成功-运行项目 基于vue-cli配置移动端自适应 转自:http://hj ...

  9. 常见的local variable 'x' referenced before assignment问题

    def fun1(): x = 5 def fun2(): x *= 2 return x return fun2() 如上代码,调用fun1() 运行会出错:UnboundLocalError: l ...

  10. [LeetCode] 643. Maximum Average Subarray I_Easy tag: Dynamic Programming(Sliding windows)

    Given an array consisting of n integers, find the contiguous subarray of given length k that has the ...