LCA的树链剖分实现
来源:互联网 发布:同性恋软件 blued下载 编辑:程序博客网 时间:2024/05/02 00:33
这篇本来是要在树链剖分小节中写的,但是我感觉这只是树链剖分的一个衍生物,所以另开了一篇,如果对树链剖分部分还不是太了解,请看上面的链接。
计算树中两个节点的最近公共祖先,我们一般有爬山法,Tarjan离线算法,或者是将LCA转换成RMQ来解,这里讲一讲一种新的求LCA的算法,它是基于树链剖分的。
我们先来复习一下树链剖分中各个节点所维护的信息:
1:siz[v]表示以v为根的子树的节点总数。
2:dep[v]表示v的深度。
3:son[v]表示与v在同一重链上的v的儿子节点。
4:fa[v]表示v的父亲节点。
5:top[v]表示v所在链的顶端节点。
(其实还有w[v],不过在这里我们不需要)
我们先来看看树链剖分求LCA的代码,然后再来看算法的原理。
int LCA(int a, int b){ while (1) { if (top[a] == top[b]) return dep[a] <= dep[b] ? a : b; else if (dep[top[a]] >= dep[top[b]]) a = fa[top[a]]; else b = fa[top[b]]; }}
是不是非常简短呢。下面来分析这个算法。
1:如果top[a]==top[b],说明a和b在同一条重链上,显然它们中深度较小的点即为它们的最近公共祖先。
2:若果top[a]!=top[b],(说明a,b在不同的重链上)且a的深度较大,则此时a,b的LCA不可能在a所在的重链上。
因为如果a,b的LCA在a所在重链上,那么top[a]显然也为a,b的公共祖先,则若dep[up[a]]]>dep[b],则显然不可能,若dep[up[a]]]<=dep[b],则设dep[up[a]]]为d,因为d>=dep[b],所以我沿着b向上搜索,在深度d处也可以找到一个点C为b的祖先,又因为a,b不在同一条重链上,所以top[a]!=C,这就意味着在同一深度,b有两个不同的祖先,这是不可能的(因为是一棵树),所以,LCA不可能在a所在的重链上。所以我们可以将a上升到up[a]的父节点,这时a,b的LCA没有变化。
3:若果top[a]!=top[b],且b的深度较大,同理我们可将b上升到up[b]的父节点。
4: a,b不停地上升,所以一定可以找到a,b的LCA。
因为我们知道,在树中任意一点到根的路径上,重链数不会超过(logn),所以我们可以在O(logn)的时间复杂度内,将a,b的LCA求出来。
因为我们求LCA都是在重链上进行,所以结合线段树,我们可以维护树中任意两点间路径的信息了,比如两点间的最大边最小边,边权和等等,这里就不一一举例了。
- LCA的树链剖分实现
- LCA之树链剖分 zhn_666的lca 模板
- LCA实现的三种不同的方法
- LCA实现的三种不同的方法
- LCA实现的三种不同的方法
- RMQ实现LCA
- 树上倍增实现lca
- LCA Tarjan实现
- bzoj3083 遥远的国度 树链剖分+树上lca
- [bzoj3083][树链剖分][lca]遥远的国度
- 【lca】lca的tarjan写法 poj1330
- POJ 1986 LCA,tarjan实现
- LCA算法实现方法介绍
- LCA的Tarjan算法
- LCA的介绍
- LCA的暴力查询
- LCA的离线算法
- LCA的RMQ求法
- 学习 alter system dump
- 介绍MSAA,UIA ,Windows Automation API
- 犯两个很二的错误关于webservice
- 界面特效中模型显示被遮挡问题
- python 遇到 syntaxerror: non-ascii character '/xd6' in file 我 教你解决
- LCA的树链剖分实现
- VSTO之旅系列(三):自定义Excel UI--转载
- fedora 自动启动的程序管理器
- 系统应用分析地址
- 软考程序员大纲与培训指南(2009年版)(3/3)
- 软考程序员大纲与培训指南(2009年…
- 软考程序员大纲与培训指南(2009年…
- 关于城镇化的几点自己的见解
- 2010年09月04日的日记