在这篇博客中,主要讲三种求LCA的方法。
tarjan
1 |
|
理解:
tarjan的基本思路基于DFS,是一种离线算法,时间复杂度为Θ(m+q)m边数,q询问数。
从根节点一路走到叶子节点。如果询问(u,v),u为当前节点,vis[v]!=0。
说明已经走过LCA(u,v)。并继续遍历LCA(u,v)的子树。
RMQ
1 |
|
理解:
RMQ解LCA是在线的算法。先将树预处理出其DFS序,LCA(U,V)一定在dfs序u和v之间。
用RMQ预处理出每段区间中深度最小的点就是他的LCA。
倍增法
1 |
|
理解:
一遍dfs处理出每个点的父亲。然后预处理出每个点往上跳2^i个点的父亲。
开始LCA时,先把两个点的深度跳到一样。然后从大到小(2^n~2^0)跳,如果fa[i][a]==fa[i][b]说明跳过了,不更新b,a,最后fa[0][a]就是他们的LCA。
提醒:
遇到大数据,输入输出一定要用scanf()和printf()。把cout换为printf()快了将近2000ms。
本文作者:
syrsteven
最后更新: 2023年09月02日 04:06:21
本文链接: http://syrsteven.github.io/post/5c4ec076.html
版权声明: 本作品采用 CC BY-NC-SA 4.0 许可协议进行许可,转载请注明出处!
最后更新: 2023年09月02日 04:06:21
本文链接: http://syrsteven.github.io/post/5c4ec076.html
版权声明: 本作品采用 CC BY-NC-SA 4.0 许可协议进行许可,转载请注明出处!