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. 51nod 1967 路径定向——欧拉回路

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1967 一共只会有偶数个奇数度的点.因为每多一条边,总度数加2. 把 ...

  2. 用Azure CLI批量上传文件

    在Windows环境下,我们可以使用AzCopy批量上传文件.其效率和传输速率都是非常快的. 在Linux或MacOS环境下,可以使用Azure的CLI实现批量文件的上传. 下面的脚本可以实现此功能. ...

  3. HDOJ1166(线段树点修改)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. Qt webview调用JavaScript 带参函数

    void MainWindow::on_pushButtonShowMarker_clicked() { QString lat = "104.701681"; QString l ...

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

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

  6. C++11新标准

    1. 新类型 long long和unsigned long long: char16_t 和 char32_t: 新增原始字符串: 2. 统一的初始化 C++11扩大了用大括号括起的列表(初始化列表 ...

  7. 把Nutch爬虫部署到Hadoop集群上

    原文地址:http://cn.soulmachine.me/blog/20140204/ 把Nutch爬虫部署到Hadoop集群上 Feb 4th, 2014 | Comments 软件版本:Nutc ...

  8. 2、linux-compress and uncompresse

    1.单个文件 压缩 解压 gzip file1  gzip -d file1.gz或者gunzip file1.gz #file1文件即会被压缩为 file1.gz,file1原文件删除:解压后同样删 ...

  9. (分享)一位资深程序员大牛给予Java初学者的学习路线建议

    摘自:http://bbs.itheima.com/thread-333038-1-1.html 如果你是在校学生,务必要在学好基础(比如计算机系统.算法.编译原理等等)的前提下,再考虑去进行下面的学 ...

  10. Django 的认证系统

    Django自带的用户认证 auth 模块 from django.contrib import autu django.contrib.auth 中提供了许多方法, 这里主要介绍其中三个: auth ...