惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
MyScale Blog
MyScale Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
人人都是产品经理
人人都是产品经理
C
Check Point Blog
宝玉的分享
宝玉的分享
B
Blog RSS Feed
博客园 - 三生石上(FineUI控件)
量子位
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
Jina AI
Jina AI
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
博客园 - 叶小钗
J
Java Code Geeks
The Cloudflare Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
腾讯CDC
P
Proofpoint News Feed
美团技术团队
H
Help Net Security
B
Blog
博客园_首页

Victrid's Personal Site

斯普拉遁3打工模式联机网络过程分析 DHCP无类型静态路由──一个摆设 配置透明代理,实现无感上网 Generating Unlimited Grammar: A Messenger Perspective LaTeX插入其他PDF中的矢量图 光速不变原理和迈克尔孙──莫雷实验 交大葡萄演义 调试微信内置浏览器 欧悌甫戎篇 苏格拉底的申辩篇 弥罗斯人的辩论 埃斯库罗斯作品:波斯人、阿伽门农 电路理论资料 Coronavirus: A Humanitarian Crisis 雨夜 linux配置SSR 二叉堆的实现 懒政 Placement New Flipped: A Love Story 我宁可呆在这样的疯人院里 谈新发本地病例 勇敢与智慧 Powerful but Limited Drafted VLC Libva Error Troubleshooting Ring-Fit新上手 政治艺术化与艺术政治化 动态规划——从分割等和子集入手 被背叛的革命 (1)
LCA 最近公共祖先
Victrid · 2020-06-03 · via Victrid's Personal Site

最近公共祖先(Lowest Common Ancestor)的定义:同一棵树的节点u,v,定义:

lca(u,v)为分别包含u、v的全部该树的子树的并集中的最小高度树的根节点。

下面介绍四种求最近公共祖先的方法。暴力法、倍增法、Tarjan算法,RMQ算法。

暴力法

标记现在的点访问过;向上跳到父节点。

重复这一过程,直到跳到的父节点被标记为访问过。

时间复杂度O(n)(还需要O(n)清除标记)。

一种不需要清除标记的优化方法:将访问标记和查询次数对应:第i次查询标记i,这样就可以不需要清除标记。

DP标记——倍增算法

标记一组f[i][j],标记i节点的上方第$2^j$个节点。

深的节点向上跳,跳到相同的高度。

可以利用DP标记向上跳:比如说深度相差7,分别跳4,2,1。

同时向上跳:同时跳到最深的不同节点,直到跳到父节点相同为止。

时间复杂度:O_{init}(nlgn),O_{query}(lgn), 空间复杂度:O(nlgn)

这是一个在线算法。

Tarjan算法

将所有的查询lca(a,e),lca(c,e),lca(d,a)建立查询集合

1
2
3
4
5
6
7
Sa={(a,e),(d,a)}

Sc={(c,e)}

Sd={(d,a)}

Se={(a,e),(c,e)}

维护并查集UFS(u)->u

一遍DFS,完成所有查询。

进入节点u:对于查询集合Su中的每一个查询lca(u,v)

  • 如果查询没有访问过,标记被访问。

  • 如果查询被访问过,lca(u,v)=UFS(v)

Union(UFS(v),UFS(father_v))->UFS(v)

这是一个离线算法。

此处的UFS为并查集:定义操作:查找find(u),并union(u,v):u<=>v

时间复杂度:O_{init}(n+m),O_{query}(n+m(lgn)), 空间复杂度:O(n)

RMQ 区间最值查询算法

区间最小值查询Range Minimum Query)的定义:对于数组list,

rmq(l,r) = min_{l<=k<r} list[k]

RMQ: Sparse Table算法

建立数组st[i][j]为区间[i,i+2^j)的区间最小值下标。

(可以递推:st[i] [j] = min{st[i][j-1],st[i+2^{j-1}][j-1]}建立)

询问:设t为r-l+1的二进制最高位数,则有

rmq(l,r) = min{st[l][t], st[r-2^t+1][t]}

因为上面的集合一定覆盖[l,r]

用RMQ解决LCA

先DFS一棵树,记录DFS顺序表为seq。

DFS顺序:DFS搜索所经过的所有节点,包括已经经过的重复节点。(长度2n-1(参考电路理论的树))

first[node]记录节点node在第一次出现的位置。

此时lca(u,v)=seq.rmq(first[u],first[v])

Ads by Google

Read our privacy policy on how these personalized advertisements are delivered to you.

For your reading experience, we provide full-text RSS feeds. Although math formulas cannot be displayed well, the interface can be adjusted as you like and there are no ads.