http://www.lydsy.com/JudgeOnline/problem.php?id=3732

首先想到,要使得最长边最短,应该尽量走最短的边,在MST上。

然后像LCA那样倍增娶个最大值

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = + ;
struct Edge {
int u, v, w, tonext;
bool operator < (const struct Edge & rhs) const {
return w < rhs.w;
}
} e[maxn], t[maxn];
int first[maxn], num;
void addEdge(int u, int v, int w) {
e[num].u = u, e[num].v = v, e[num].w = w, e[num].tonext = first[u];
first[u] = num++;
}
int tfa[maxn];
int tofind(int u) {
if (tfa[u] == u) return u;
else return tfa[u] = tofind(tfa[u]);
}
const int need = ;
int mx[maxn][];
int ansc[maxn][], deep[maxn], fa[maxn]; //所有只需初始值,不需要初始化。
void init_LCA(int cur) { //1 << 20就有1048576(1e6)了。
ansc[cur][] = fa[cur]; //跳1步,那么祖先就是爸爸
if (cur != ) {
for (int i = first[fa[cur]]; ~i; i = e[i].tonext) {
int v = e[i].v;
if (v == cur) {
mx[cur][] = e[i].w;
break;
}
}
}
int haha = mx[cur][];
for (int i = ; i <= need; ++i) { //倍增思路,递归处理
ansc[cur][i] = ansc[ansc[cur][i - ]][i - ];
mx[cur][i] = mx[ansc[cur][i - ]][i - ];
mx[cur][i] = max(mx[cur][i], haha);
haha = max(haha, mx[cur][i]); //上到极限的时候需要取个路经的最大值。
}
for (int i = first[cur]; ~i; i = e[i].tonext) {
int v = e[i].v;
if (v == fa[cur]) continue;
fa[v] = cur;
deep[v] = deep[cur] + ;
init_LCA(v);
}
}
int LCA(int x, int y) {
int res = ;
if (deep[x] < deep[y]) swap(x, y); //需要x是最深的
for (int i = need; i >= ; --i) { //从大到小枚举,因为小的更灵活
if (deep[ansc[x][i]] >= deep[y]) { //深度相同,走进去就对了。就是要去到相等。
res = max(res, mx[x][i]);
x = ansc[x][i];
}
}
if (x == y) return res;
for (int i = need; i >= ; --i) {
if (ansc[x][i] != ansc[y][i]) { //走到第一个不等的地方,
res = max(res, mx[x][i]);
res = max(res, mx[y][i]);
x = ansc[x][i];
y = ansc[y][i];
}
}
res = max(res, mx[x][]);
res = max(res, mx[y][]);
return res; //再跳一步就是答案
} void work() {
num = ;
memset(first, -, sizeof first);
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for (int i = ; i <= n; ++i) tfa[i] = i;
for (int i = ; i <= m; ++i) {
scanf("%d%d%d", &t[i].u, &t[i].v, &t[i].w);
}
sort(t + , t + + m);
int sel = ;
for (int i = ; i <= m; ++i) {
if (sel == n - ) break;
int x = tofind(t[i].u), y = tofind(t[i].v);
if (x == y) continue;
sel++;
tfa[y] = x;
addEdge(t[i].u, t[i].v, t[i].w);
addEdge(t[i].v, t[i].u, t[i].w);
}
fa[] = , deep[] = ;
init_LCA();
// printf("%d\n", mx[2][1]);
for (int i = ; i <= k; ++i) {
int u, v;
scanf("%d%d", &u, &v);
printf("%d\n", LCA(u, v));
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

bzoj 3732: Network 树上两点边权最值的更多相关文章

  1. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  2. BZOJ 3732: Network 最小生成树 倍增

    3732: Network 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 &l ...

  3. BZOJ 3732 Network 【模板】kruskal重构树

    [题解] 首先,我们可以发现,A到B的所有路径中,最长边的最小值一定在最小生成树上.我们用Kruskal最小生成树时,假设有两个点集U,V,若加入一条边w(u,v)使U,V联通,那么w就是U中每个点到 ...

  4. [bzoj 3732] Network (Kruskal重构树)

    kruskal重构树 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第 ...

  5. BZOJ 3732 Network

    2016.1.28 纪念我BZOJ第一题 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= ...

  6. BZOJ 3732 Network Link-Cut-Tree (我是认真的!!

    题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 LCT的裸题! 首先维护一个动态的最小生成树,然后每次增加边时删除两点间路径上权值最大的边.最后询问时直接求x到y ...

  7. bzoj 3732 Network(最短路+倍增 | LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3732 [题意] 给定一个无向图,处理若干询问:uv路径上最长的边最小是多少? [思路一 ...

  8. 【刷题】BZOJ 3732 Network

    Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_ ...

  9. BZOJ 3732 Network —— 最小生成树 + 倍增LCA

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 <= N <= 15, ...

随机推荐

  1. mongodb数据迁移的两种方式

    环境说明:bbs数据采集的数据越来越多,目前是50G,每天大概以200W的数据量增长.而当前服务器1.2上面的空间不足,需要把数据迁移到空间足够大的1.3上面去 尝试了2种方式对数据进行迁移,一种是r ...

  2. NET Remoting 最简单示例

    NET Remoting 最简单示例 2014-01-21 15:29 10492人阅读 评论(4) 收藏 举报  分类: .NET(6)  版权声明:本文为博主原创文章,未经博主允许不得转载. 学习 ...

  3. Python xlrd、xlwt、xlutils修改Excel文件-OK

    一.xlrd读取excel 这里介绍一个不错的包xlrs,可以工作在任何平台.这也就意味着你可以在Linux下读取Excel文件. 首先,打开workbook:    import xlrdwb = ...

  4. (转)JAVA中的权限修饰符

    注:本博文是转载的,原文地址:http://blog.csdn.net/xk632172748/article/details/51755438 Java中修饰符总结: 访问控制修饰符 访问控制修饰符 ...

  5. Material使用09 MdCheckboxModule、MdMenuModule、MdTooltipModule

    1 MdCheckboxModule的使用 md-checkbox 实现的功能和  <input type="checkbox">  相同,只不过 md-checkbo ...

  6. .Net开发中的@ 和 using 使用技巧

    一.@符号的妙用 1.可以作为保留关键字的标识符 C#规范当中,不允许使用保留关键字(class.bool等)当作普通的标识符来命名,这时候@符号作用就体现 出来了,可以通过@符号前缀把这些保留关键字 ...

  7. Unity3d 控制物体移动、旋转、缩放

    在Unity中通过利用 Input Manager(输入管理器)可以很简单的实现对一个物体进行移动.旋转.缩放操作. 演示代码: //通过虚拟轴控制物体移动.旋转.缩放 public class Mo ...

  8. DES的雪崩效应分析

    明文固定,密钥改变一个字节 假定明文为11111111(00000001 00000001 00000001 00000001 00000001 00000001 00000001 00000001) ...

  9. 【原创】谈谈redis的热key问题如何解决

    引言 讲了几天的数据库系列的文章,大家一定看烦了,其实还没讲完...(以下省略一万字). 今天我们换换口味,来写redis方面的内容,谈谈热key问题如何解决. 其实热key问题说来也很简单,就是瞬间 ...

  10. c++常考算法知识点汇总

    前言:写这篇博客完全是给自己当做笔记用的,考虑到自己的c++基础不是很踏实,只在大一学了一学期,c++的面向对象等更深的知识也一直没去学.就是想当遇到一些比较小的知识,切不值得用一整篇 博客去记述的时 ...