樹上倍增 求LCA u,v

2021-10-01 20:45:10 字數 1527 閱讀 3124

求lca(u,v)的三種方法:

1:rmq+dfs()序

2:並查集+dfs()

3:樹上倍增

然而聽說1,2兩種方法不怎麼火熱,3是目前最受歡迎的,故我就跟隨大眾潮流,學了樹上倍增求lca(u,v)的方法

樹上倍增:利用了rmq的思想,首先定義乙個pre[i][j]陣列,pre[i][j]表示i往上走2^j層所表示的父輩,根據倍增關係,我們可以得到:pre[i][j]=pre[pre[i][j-1]][j-1],然後我們利用dfs()處理每乙個點的深度:

depth[u]

=depth[fa]

+1

並根節當前節點的深度,倍增u所能達到的點

**:

void

dfs(

int u,

int fa)

//求深度

}}

lca:

lca利用倍增後的陣列進行二進位制拆分,當depth[u]depth[v]不相同時,讓depth[u]depth[v]相同,如果u==v說明最近公共最祖先時u,如果不相等,就在同一深度進行二進位制差分式倍增,然後最終得到pre[u][0]是最近公共祖先

例題:洛谷lca模板題

ac**:

#include.h>

using namespace std;

//樹上倍增求lca

const

int maxn=

5e5+5;

//vectorvec[maxn];

struct node

edge[maxn*2]

;int pre[maxn][32

],depth[maxn]

,head[maxn]

;int n,q,root,cnt;

void

add(

int u,

int v)

void

dfs(

int u,

int fa)

//求深度}}

intlca

(int u,

int v)}if

(u==v)

for(j=i; j>=

0; j--)}

return pre[u][0

];}int

main()

dfs(root,0)

;while

(q--

)}

樹上倍增法求LCA

我們找的是任意兩個結點的最近公共祖先,那麼我們可以考慮這麼兩種種情況 1.兩結點的深度相同.2.兩結點深度不同.第一步都要轉化為情況1,這種可處理的情況。先不考慮其他,我們思考這麼乙個問題 對於兩個深度不同的結點,把深度更深的那個向其父節點迭代,直到這個迭代結點和另乙個結點深度相同,那麼這兩個深度相...

演算法 樹上倍增求LCA

lca指的是最近公共祖先 least common ancestors 如下圖所示 4和5的lca就是2 那怎麼求呢?最粗暴的方法就是先dfs一次,處理出每個點的深度 然後把深度更深的那乙個點 4 乙個點地乙個點地往上跳,直到到某個點 3 和另外那個點 5 的深度一樣 然後兩個點一起乙個點地乙個點地...

12 16 樹上倍增法求LCA

1.預處理 節點的深度d 到根節點的距離dist 該點向上走2 k步能夠到達的點 f陣列。2.lca 將兩個節點調整到同乙個深度,只調整深的那個即可。如果 結束後,這兩個點重合,說明該點就是所求的點。否則,從大往小開始試跳躍的步數,直至將這兩個點調整為目標點的兩個子節點。最後兩點的父節點就是所求的l...