LCA-ST算法&Tarjan_LCA
来源:互联网 发布:奥特歌词软件 编辑:程序博客网 时间:2024/04/29 07:53
定义
树中两个节点x,y的最近公共祖先(Lowest Common Ancestors,简称LCA)指的是既是x祖先,又是y祖先且距离x和y最近的节点。
ST算法(在线)
我们有一个求x和y的LCA的初始想法:就是先让x和y中dep较大的节点与dep较小的节点处在同一深度,然后同时向上走,直到相遇,此时相遇的节点即为LCA:
复杂度为
初始想法很明显的一个缺陷是:每次只走一层,太慢了,而这和RMQ初始想法的缺陷是一样的。所以我们会想到ST算法!记录fa[i][j]表示i向上走2^j次到达的节点(我们认为根向上走若干次会到达自己),那么很容易得到转移: fa[i][j]=fa[fa[i][j-1]][j-1]
ps:我们还可以类似的记录其他信息,比如MAX[i][j]表示i向上走2^j次经过的边(点)权的最大值,从而求出一条路径中边(点)权的最大值。
构造好fa之后,如何求x到y的LCA呢?如下(不妨设dep[x]>dep[y]):
1.从大到小枚举i(
2.如果x=y,则x(y)即为LCA,结束。
3.从大到小枚举i(
4.令x=fa[x][0],此时的x即为LCA。
复杂度为
Tarjan_LCA(离线)
求LCA还有个离线算法Tarjan,Tarjan的想法是先把所有询问存下来,然后一次性全部处理,所以是离线的。过程如下:
1.用DFS遍历这棵树(优先处理出子树)。
2.假设目前遍历的点是x,子树son已经处理完毕,那么将x与son用并查集合并。
3.枚举与x有关的询问(x,y),如果y已经访问过,那么LCA(x,y)=getfa(y)即y目前的祖先。
这里简要说明一下为什么LCA(x,y)=getfa(y):
由于y已经访问过,根据深度优先搜索DFS的性质,一定有dep[y]>=dep[x]。
因为y在x之前被访问,所以y必定已经和LCA处于同一个连通块中。而且x还没处理完毕,意味着LCA也没处理完毕,所以LCA必定是这个连通块的祖先。
还有一个小问题,就是我们怎么保证y已经访问过了呢?如果没有访问过,不是无法处理出LCA了?所以我们对于一个询问(x,y),还需要添加询问(y,x),这样就可以方便的解决这个问题了。
由于并查集路径压缩之后可以视为常数,所以复杂度为
模板题
HDU2586,题解传送门。
- LCA-ST算法&Tarjan_LCA
- LCA(st算法)
- ST算法与LCA
- LCA st算法
- LCA在线算法ST算法
- LCA在线算法ST算法
- LCA算法-ST在线算法
- LCA之ST算法模板
- LCA(dfs+st)在线算法
- RMQ算法以及LCA的ST算法。
- HDU 3078 - Network(LCA'ST算法)
- hdu 2586 lca-st在线算法
- RMQ转换LCA模板 ST算法
- LCA在线算法ST&&DFS->POJ1330&&POJ1470
- 浅谈LCA的在线算法ST表
- LCA之倍增及ST算法
- LCA之ST算法模板 poj-1986
- hdu2586 LCA入门(在线算法ST)
- 二叉树的非递归遍历
- struts拦截器
- Android自动化测试之——总述
- Maven
- 《数据结构学习与实验指导》5-6:航空公司VIP客户查询
- LCA-ST算法&Tarjan_LCA
- Python学习tips(1)
- 重复数据删除(De-duplication)技术研究
- 大学的第一次演讲
- 大白话讲解Promise(二)—Promise A+ 规范
- socket半关闭
- 前不可知后不可恋
- 了解Cookie和Session
- LSTM与GRU结构