對於兩個節點的lca,根據兩個節點的關係分為一下兩種:
一、其中一方是另一方的祖先
那u和v的公共祖先就是是祖先的那一方
二、雙方都不是對方的祖先
u和v的祖先x的深度比u和v小,我們先找出u和v中深度較大的乙個,然後讓其向上跳,直到兩個節點的深度相同,當深度相同時,兩個節點開始同時往上跳,直到兩個節點重合即停止,可以發現這種方法也適用於第一種情況。
那倍增法是如何做的呢?
它的核心思想其實就是對於每個節點求出它跳2^k次的對應的節點。
那我在求解的時候,如果需要跳n次,我們把n轉為二進位制,跳logn次就可以求出對應的節點。
所以它需要維護兩個陣列
陣列dep dep[i]表示i節點的深度 可以dfs求出
陣列 g g[i][j]表示節點i跳2^j次對應的節點 它的遞迴表示式為 g[i][j]=g[g[i][j-1]][j-1]
詳見**和注釋:
相關題目:const
int maxn=
1e5+50;
int dep[maxn]
,g[maxn][21
];inline
intlca
(int x,
int y)
inline
void
dfs(
int x,
int fa)
1.洛谷p1967 貨車運輸
lca+生成樹
題解
LCA倍增演算法
一.倍增演算法的前期鋪墊 我們記節點v到根的深度為depth v 那麼如果節點w是節點u和節點v的最近公共祖先的話,讓u往上走 depth u depth w 步,讓v往上走 depth v depth w 步,都將走到節點w。因此,我們首先讓u和v中較深的乙個往上走 depth u depth v...
LCA的倍增演算法
lca,即樹上兩點之間的公共祖先,求這樣乙個公共祖先有很多種方法 每次將深度大的點往上移動,直至二者相遇 在o 2n 預處理重鏈之後,每次就將深度大的沿重鏈向上,直至二者在一條鏈上 先記錄所有的詢問,對樹進行一次dfs,對於搜尋到的點u,先將點u往下搜,再將點u與父節點所在集合合併,之後對於它的所有...
lca倍增演算法模板
時間限制 1 sec 記憶體限制 128 mb 提交 244 解決 36 提交 狀態 給一棵樹,節點數為n 1 n 250,000 和q 0 q 100,000 個詢問,對於每個詢問求出所求兩點的最近公共祖先 第一行 節點數n 以下n行,第i 1行 點i的父親節點father i 假定根的父親是0 ...