离线快速LCA(最近公共祖先) Tarjan算法

前言

对于 OIer 来说,LCA 一直是处理树上问题的好帮手,无论是倍增还是树剖都有着优秀的 \(\log n\) 的复杂度。不过由于我们(数据规模)的上进,需要更快速求 LCA,于是就有了……

反正之前打死我都不相信这玩意能离线,还能 O(1)

算法思路

首先来一棵树:

我们然后我们将要求 LCA 的点对之间加上一条虚边:

如图,我们将对求点 (7,5)、(8,9)、(11,3) 的 LCA。

一开始每个节点属于一个并查集。

接下来我们通过原树边 DFS 遍历每一个节点,在该节点 \(u\) 的子树遍历完成之后,通过该节点 \(u\) 的虚边遍历与之求 LCA 的节点 \(v\)。

此时如果 \(v\) 已经通过原树边遍历过,那么他们的 LCA 等于 \(v\) 节点的并查集根节点。

反之则不进行任何操作。

然后节点 \(u\) 的并查集祖先设为 \(u\) 在原树上的父亲。

解释一下原理:

当前 \(u\) 子树已经遍历过以后,子树 \(u\) 的并查集根节点的子树 \(t\) 一定还没有遍历完,也就是说此时还在遍历 \(t\) 的子树,如果与节点 \(v\) 要求 LCA 的节点是 \(u\),且此时 \(v\) 通过虚边遍历到了 \(u\)。

不难发现 \((u,v)\) 的公共祖先肯定有 \(t\),而 \(u\) 和 \(v\) 又属于节点 \(t\) 不同的分支,所以 \((u,v)\) 的最近公共祖先就是 \(t\)。

这种通过并查集连接祖先求 LCA 的方法十分巧妙。

CODE

inline void dfs(int u)
{
for(ri i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(vis[v]) continue;
dfs(v);
fa[v]=u;//并查集连向父亲
}
for(pair<int,int> i:EL[u])//遍历虚边
{
if(vis[i.F]) Lca[i.S]=frt(i.F);//frt 求该并查集的根
}
vis[u]=1;//遍历标记
}
//i.F 是节点的编号,i.S 是问题的编号

时间复杂度分析

预处理 \(O(n)\),处理完直接使用 \(O(1)\)。

总时间 \(O(n)\),均摊 \(O(1)\)。

练习

P3379 【模板】最近公共祖先(LCA)

P3128 【USACO15DEC】 Max Flow P

离线快速LCA(最近公共祖先) Tarjan算法的更多相关文章

  1. LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现

    首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵 ...

  2. LCA 最近公共祖先 tarjan离线 总结 结合3个例题

    在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...

  3. HDU 4547 CD操作 (LCA最近公共祖先Tarjan模版)

    CD操作 倍增法  https://i.cnblogs.com/EditPosts.aspx?postid=8605845 Time Limit : 10000/5000ms (Java/Other) ...

  4. LCA最近公共祖先——Tarjan模板

    LCA(Lowest Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. Tarjan是一种离线算法,时间复杂度O(n+Q),Q表示询问次数,其中 ...

  5. LCA最近公共祖先 Tarjan离线算法

    学习博客:  http://noalgo.info/476.html 讲的很清楚! 对于一颗树,dfs遍历时,先向下遍历,并且用并查集维护当前节点和父节点的集合.这样如果关于当前节点(A)的关联节点( ...

  6. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  7. LCA(最近公共祖先)算法

    参考博客:https://blog.csdn.net/my_sunshine26/article/details/72717112 首先看一下定义,来自于百度百科 LCA(Lowest Common ...

  8. LCA 近期公共祖先 小结

    LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...

  9. LCA(最近公共祖先)模板

    Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...

  10. LCA近期公共祖先

    LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...

随机推荐

  1. LaTeX 插入伪代码

    使用 algorithm 包和 algpseudocode 包 algorithm 包 用途: 提供一个浮动体环境来包含算法(类似于 figure 和 table 环境),使得算法可以自动编号并出现在 ...

  2. git merge 详细操作,看完就懂

    [root@hostname git_test]# git init hint: Using 'master' as the name for the initial branch. This def ...

  3. Blockchain A-Z™: Learn How To Build Your First Blockchain

    单纯从技术角度了解blockthain. Module 1, Blockchain 特点: 分布式的,不可篡改的,p2p的 网络.存储在每个node上保存一份,这就是个基于网络的RAID 1 啊,感觉 ...

  4. .NET 9 中 LINQ 新增的功能

    LINQ介绍 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称.数据查询历来都表示为简单的字符串,没有编译时类型检查或 IntelliSense 支持.此外,需要针对每种 ...

  5. react-pdf预览在线PDF的使用

    1.在react项目中安装react-pdf依赖包 建议安装8.0.2版本的react-pdf,如果安装更高版本的可能出现一些浏览器的兼容性问题: npm install react-pdf@8.0. ...

  6. el-table

    el-table-column 渲染的顺序不对,第一列被渲染到最后 el-table-column 必须作为 el-table 或 el-table-column 的直接子元素使用,如果不是将会导致标 ...

  7. 伯克利函数调用排行榜(BFCL)

    自 2022 年底以来,大语言模型(LLMs)凭借其执行通用任务的强大能力,成为众人关注的焦点.不仅限于聊天应用,将这些模型应用于开发各类 AI 应用和软件(如 Langchain, Llama In ...

  8. 全网最适合入门的面向对象编程教程:54 Python字符串与序列化-字符串格式化与format方法

    全网最适合入门的面向对象编程教程:54 Python 字符串与序列化-字符串格式化与 format 方法 摘要: 在 Python 中,字符串格式化是将变量插入到字符串中的一种方式,Python 提供 ...

  9. 45. beforeCreate和created的区别

    data数据和methods的方法是否存在,是否定义了 : beforeCreate 都是 undefiend :

  10. 斜率优化DP简单总结&&“土地购买”题解

    今天刚刷完了斜率优化DP,简单从头回顾一下. \[首先,能写出DP方程应该是最重要的,毕竟斜率只是用来优化的 \] 那么一个DP方程能用斜率优化,具备一种形式: \[f[i]+s1[i]+A[i]*B ...