LCA的倍增演算法

2021-10-02 06:01:22 字數 773 閱讀 3412

對於兩個節點的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 ...