節點的最近公共祖先(LCA倍增法)

2021-09-18 01:36:14 字數 1660 閱讀 7259

樹是一種很常見的資料結構。現在蒜頭君面臨乙個問題,在乙個有 n 個節點的樹上,節點編號分別是1…n。蒜頭想知道一些節點之間的最近公共祖先是那些節點。

輸入格式

第一行輸入乙個整數 n(2≤n≤10,000),表示樹上有 n 個節點。

接下來的 n−1 行,每行輸入倆個整數 a,b(1≤a,b≤n)代表節點 a,b 之間有一條 a 到 b 邊,a 是 b 的父親。

接下來輸入乙個整數 q,代表蒜頭君的 q 次提問。(1≤q≤1,000)

接下來的 q 行,每行輸入倆個整數 c,d(1≤c,d≤n)代表詢問 c,d 倆個節點的最近公共祖先。

輸出格式

對於每次詢問,輸出公共祖先的節點編號,佔一行。

樣例輸入

51 2

2 31 4

2 52

3 43 5

樣例輸出12

#include

#include

#include

#include

using namespace std;

const

int maxn=

1e4+1;

//最大的點數

struct edge

edge

(int _v,

int _next):v

(_v)

,next

(_next)

//建構函式

}e[maxn]

;int p[maxn]

,vst[maxn]

,d[maxn]

,fa[maxn][20

];//儲存邊的序號的頭指標,標記陣列,儲存深度,fa[i][j]為i往上走(2^j)層的序號

void

dfs(

int u)}}

intlca

(int x,

int y)

int i,j;

for(i=0;

(1<<=d[x]

;++i)

;//找出(2^i<=n),找出i的最大值,保證不會超出樹

--i;

//深的節點先往上走,走到和y節點同一層

for(j=i;j>=0;

--j)}if

(x==y)

return x;

//若走到同一層時,兩者相等,則y就是原先節點的父節點

for(j=i;j>=0;

--j)

if(fa[x]

[j]!=fa[y]

[j])

}return fa[x][0

];//此時x和y的父節點就是最近公共祖先

}int

main()

int root;

for(

int i=

1;i<=n;

++i)

}memset

(d,-1,

sizeof

(d))

;dfs

(root)

;for

(int level=1;

(1<<=n;

++level)

}int q;

scanf

("%d"

,&q)

;while

(q--

)}

模板 LCA 最近公共祖先 倍增法

2019 11 07 09 25 45 c.樹之呼吸 叄之型 樹上兩點路徑長度 time limit 1000 ms memory limit 32768 k total submit 7 4 users total accepted 2 2 users special judge no descr...

LCA最近公共祖先 倍增法筆記

先暫時把模板寫出來,a幾道題再來補充 此模板也是洛谷上的一道模板題 pragma gcc optimize 2 o2優化 include using namespace std typedef long long ll const int l 30 2的指數的大小 const int nn 1e6 ...

倍增法求lca(最近公共祖先)

基本上每篇部落格都會有參考文章,一是彌補不足,二是這本身也是我學習過程中找到的覺得好的資料 大致上演算法的思路是這樣發展來的。想到求兩個結點的最小公共祖先,我們可以先把兩個的深度提到同一水平,在一步一步往上跳,直到兩個結點有了乙個公共祖先,依照演算法流程,這就是least common ancest...