bzoj 3732: Network 树上两点边权最值
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 树上两点边权最值的更多相关文章
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- BZOJ 3732: Network 最小生成树 倍增
3732: Network 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 &l ...
- BZOJ 3732 Network 【模板】kruskal重构树
[题解] 首先,我们可以发现,A到B的所有路径中,最长边的最小值一定在最小生成树上.我们用Kruskal最小生成树时,假设有两个点集U,V,若加入一条边w(u,v)使U,V联通,那么w就是U中每个点到 ...
- [bzoj 3732] Network (Kruskal重构树)
kruskal重构树 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第 ...
- BZOJ 3732 Network
2016.1.28 纪念我BZOJ第一题 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= ...
- BZOJ 3732 Network Link-Cut-Tree (我是认真的!!
题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 LCT的裸题! 首先维护一个动态的最小生成树,然后每次增加边时删除两点间路径上权值最大的边.最后询问时直接求x到y ...
- bzoj 3732 Network(最短路+倍增 | LCT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3732 [题意] 给定一个无向图,处理若干询问:uv路径上最长的边最小是多少? [思路一 ...
- 【刷题】BZOJ 3732 Network
Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_ ...
- BZOJ 3732 Network —— 最小生成树 + 倍增LCA
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 <= N <= 15, ...
随机推荐
- Netty组件
一.Channel.EventLoop 和ChannelFuture 这些类合在一起,可以被认为是Netty 网络抽象的代表: Channel—Socket: EventLoop—控制流.多线程处理. ...
- 杂项-权限管理:Spring Secutity
ylbtech-杂项-权限管理:Spring Secutity Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在S ...
- rails Ajax--利用Jquery
view function init_tree(product_name) { var htmlobj=$.ajax({url: "get_all_file?param=" + p ...
- SVN客户端下载和Svn visual studio插件
1.Visual SVN Visual SVN visual studio插件 https://www.visualsvn.com/vis... 2.TortoiseSVN SVN客户端下载 http ...
- 每天一道算法题(4)——O(1)时间内删除链表节点
1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...
- ls- 查看文件信息
通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限),查看目录信息等等,ls 命令在日常的linux操作中用的很多,在此给大家介绍一下ls 命令的使 ...
- Linux Shell 脚本提示:sleep: 无效的时间间隔"1s\r"
问题:编写好的 Shell 脚本在 Linux 执行时提示报错:sleep: 无效的时间间隔"1s\r" : 原因:若再三确认脚本没有写错,可能是原脚本文件在 Win 下创建编写好 ...
- eclipse中导入项目后提示错误:The project was not built due to"Could not delete'/文件夹路径名
eclipse中导入项目 1.新建一个项目: 2.把已存在的项目的所有文件复制到该新建的项目下: 3.把lib文件夹中的jar导入:(右键-)add into path……): 4.常见问题如下 ec ...
- 《鸟哥的Linux私房菜》读书笔记4
1. grep查找 grep 'string' filename; last | grep 'root'; 以行为单位. 利用参数-i(忽略大小写),-v(反相)等进行正则表达式: ‘’中可以为正则表 ...
- 20169219linux 内核原理与分析第四周作业
系统调用 系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核唯一的合法入口. 一般情况下,应用程序通过在用户空间实现的应用编程接口(API)而不是直接通过系统调用来编程. 要访问系统调用 ...