「学习笔记」tarjan求最近公共祖先
Tarjan 算法是一种 离线算法,需要使用并查集记录某个结点的祖先结点。
并没有传说中的那么快。
过程
将询问都记录下来,将它们建成正向边和反向边。
在 dfs 的过程中,给走过的节点打上标记,同时维护并查集,这里利用了回溯的思想,如果 \(u\) 节点的这棵子树没搜完,那么 fa[u] = u;,搜完后,在更新并查集。
我们假设查询 \(u\) 和 \(v\) 的最近公共祖先,搜到节点 \(u\),如果另一个节点 \(v\) 已经被搜到过了,那么 \(v\) 点的并查集祖先就是 \(u\) 和 \(v\) 的最近公共祖先。
如果第一次查询 \(v\) 点时,发现 \(v\) 点已经被搜到了,说明 \(u\) 和 \(v\) 点在同一棵子树中,并且这个子树是所有包括了 \(u\) 点和 \(v\) 点的子树中
siz最小的,这棵子树的根也是在所有符合条件的子树的根中离 \(u\) 和 \(v\) 最近的,即这棵子树的根就是 \(u\) 和 \(v\) 的最近公共祖先,而 \(v\) 的并查集祖先就是这个根节点。
代码
结构体记录询问
int cnt = 1;
struct query {
int v, lca, nxt;
} q[N << 1];
记录询问、初始化
for (int i = 1, x, y; i <= m; ++ i) {
scanf("%d%d", &x, &y);
add_query(x, y);
add_query(y, x);
}
for (int i = 1; i <= n; ++ i) {
fa[i] = i;
}
tarjan、并查集
void tarjan(int u) {
fa[u] = u;
vis[u] = 1;
for (int v : son[u]) {
if (!vis[v]) {
tarjan(v);
fa[v] = u;
}
}
int v;
for (int i = h[u]; i; i = q[i].nxt) {
if (vis[v = q[i].v]) {
q[i].lca = q[i ^ 1].lca = find(v);
}
}
}
fa[u] = u; 是为了保证在 \(u\) 这棵子树没有搜完的情况下,让它子树里的节点的并查集找祖先时找到的是它。
「学习笔记」tarjan求最近公共祖先的更多相关文章
- 「学习笔记」Min25筛
「学习笔记」Min25筛 前言 周指导今天模拟赛五分钟秒第一题,十分钟说第二题是 \(\text{Min25}\) 筛板子题,要不是第三题出题人数据范围给错了,周指导十五分钟就 \(\text{AK ...
- 「学习笔记」FFT 快速傅里叶变换
目录 「学习笔记」FFT 快速傅里叶变换 啥是 FFT 呀?它可以干什么? 必备芝士 点值表示 复数 傅立叶正变换 傅里叶逆变换 FFT 的代码实现 还会有的 NTT 和三模数 NTT... 「学习笔 ...
- 「学习笔记」字符串基础:Hash,KMP与Trie
「学习笔记」字符串基础:Hash,KMP与Trie 点击查看目录 目录 「学习笔记」字符串基础:Hash,KMP与Trie Hash 算法 代码 KMP 算法 前置知识:\(\text{Border} ...
- 「学习笔记」平衡树基础:Splay 和 Treap
「学习笔记」平衡树基础:Splay 和 Treap 点击查看目录 目录 「学习笔记」平衡树基础:Splay 和 Treap 知识点 平衡树概述 Splay 旋转操作 Splay 操作 插入 \(x\) ...
- 「学习笔记」FFT 之优化——NTT
目录 「学习笔记」FFT 之优化--NTT 前言 引入 快速数论变换--NTT 一些引申问题及解决方法 三模数 NTT 拆系数 FFT (MTT) 「学习笔记」FFT 之优化--NTT 前言 \(NT ...
- 「学习笔记」Treap
「学习笔记」Treap 前言 什么是 Treap ? 二叉搜索树 (Binary Search Tree/Binary Sort Tree/BST) 基础定义 查找元素 插入元素 删除元素 查找后继 ...
- 「学习笔记」wqs二分/dp凸优化
[学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...
- 「学习笔记」倍增思想与lca
目录 ST表 算法 预处理 查询 关于 log2 Code 预处理 查询 例题 P2880 P2048 lca 树上 RMQ 前置知识:欧拉序列 算法 Code 离线 Tarjan 算法 Code 倍 ...
- 「学习笔记」ST表
问题引入 先让我们看一个简单的问题,有N个元素,Q次操作,每次操作需要求出一段区间内的最大/小值. 这就是著名的RMQ问题. RMQ问题的解法有很多,如线段树.单调队列(某些情况下).ST表等.这里主 ...
- 「学习笔记」递推 & 递归
引入 假设我们想计算 \(f(x) = x!\).除了简单的 for 循环,我们也可以使用递归. 递归是什么意思呢?我们可以把 \(f(x)\) 用 \(f(x - 1)\) 表示,即 \(f(x) ...
随机推荐
- keshe
keshe 发送方a 代码: package org.example; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.ut ...
- win服务项因各种原因出问题,删除注册表服务项
win7系统,可以cmd–>sc delete 服务名称win10计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 删除相关服务即 ...
- Undelivered Mail Returned to Sender
电子邮件是使用电子邮件地址application@sample.com从Application发送的. 出于业务原因我们无法在此应用程序中更新/删除无效的外部电子邮件地址,因此响应出站电子邮件会生成许 ...
- class3
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<windows.h> #d ...
- 使用yarn启用项目,报错无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\yarn.ps1,因为在此系 统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
这是由于新版win10 安装的时候会出现: 解决 搜索powershell,右键以管理员身份运行 2.打开之后,执行命令set-ExecutionPolicy RemoteSigned更改 Power ...
- 在MDK 5中打开MDK 4工程要注意的问题1
我是生手,对于MDK的理解还很简单.以下内容是遇到的一种情况. 有一个MDK 4工程,要求顺序点亮4个LED灯,工程已经建好. 在MDK 5中打开,编译都没问题,要烧写时,提示"can no ...
- 给临时停车号码牌插上翅膀:lua脚本语言加入—鲁哇客智能挪车号码牌技术升级之路
预计6月中旬上线的,带语音的智能挪车号码牌,会新增lua编程脚本的支持.类似于我们的手机,从功能机到智能机的进化,有着划时代的意义:产品功能不再由厂家决定,她可由lua编程脚本书写,随时编辑修改. l ...
- Python批量采集百度资讯文章,如何自定义采集日期范围
01 引言 大家好!蜡笔小曦有个朋友是做能源相关工作的,她想要有一个工具以天为单位持续地采集百度资讯中能源相关的文章进行留存和使用. 其中有个需求点是说能够自定义采集的开始日期和结束日期,这样更加灵活 ...
- Asp-Net-Core开发笔记:使用RateLimit中间件实现接口限流
前言 最近一直在忙(2月份沉迷steam,3月开始工作各种忙),好久没更新博客了,不过也积累了一些,忙里偷闲记录一下. 这个需求是这样的,我之前做了个工单系统,现在要对登录.注册.发起工单这些功能做限 ...
- 带你深入Java Log框架,彻底搞懂Log4J、Log4J2、LogBack,SLF4J
最近系统被扫出来还在使用老旧的log4j,需要升级到最新的log4j.但是在升级的发现,Java相关的日志处理库有log4j, log4j2,slf4j和logback,初一看确实有点头大,那么区别是 ...