題目描述
如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。
輸入格式
第一行包含三個正整數 n,m
,sn,m,s
n,m,
s,分別表示樹的結點個數、詢問的個數和樹根結點的序號。
接下來 n−1
n-1n−
1 行每行包含兩個正整數 x,y
x, y
x,y,表示 x 結點和 y 結點之間有一條直接連線的邊(資料保證可以構成樹)。
接下來 m
mm 行每行包含兩個正整數 a,b
a, b
a,b,表示詢問 a 結點和 b 結點的最近公共祖先。
輸出格式
輸出包含 m 行,每行包含乙個正整數,依次為每乙個詢問的結果。
輸入輸出樣例
輸入 #1
1 2 3
輸出 #1
2輸入 #2
1 5 3
輸出 #2
2知識點:lca問題:
定義:基於有根樹最近公共祖先問題
在有根樹t中,詢問乙個距離根最遠的結點x,使得x同時為結點u、v
u、vu、
v的祖先,這個祖先節點即為lca
lcalc
a。同時lca
lcalc
a一定是u、v
u、vu、
v路徑上的點。
解題思路
我們可以有這樣乙個思路,先讓u、v
u、vu、
v中深度大的那個點先往上走,直到兩點深度相同。然後一起往上走,知道兩點相遇,這個點就是lca
lcalc
a。接著我們想,如果我們每次只走一步,顯然單次查詢lca複雜度為o(n
)o(n)
o(n)
。那有沒有在空間合適的條件下更好的演算法呢?——我們可以用倍增 倍增 的思想
想要實現這個演算法,首先我們要記錄各個點的深度和他們2
i2^i
2i級的的祖先,用陣列dep
depde
p表示每個節點的深度,f[i
][j]
f[i][j]
f[i][j
]表示節點i
ii的2
j2^j
2j級祖先。 這樣如果我們需要走k步,那只需要跳o(l
ogn)
o(logn)
o(logn
)次即可。
轉移:
這個轉移可以說是演算法的核心之一,意思是i
ii的2
i2^i
2i祖先等於i
ii的2(i
−1)2^(i-1)
2(i−1)
祖先的2(i
−1)2^(i-1)
2(i−1)
祖先 ,也就是走2
j2^j
2j步相當於先走2(j
−1)2^(j-1)
2(j−1)
步再走2(j
−1)2^(j-1)
2(j−1)
步。**如下:
void
dfs(int x,int fa)
預處理完畢後,我們就可以去找它的lca
lcalc
a了,為了讓它跑得快一些,我們可以加乙個常數優化。。。(來自洛谷提高組講義)
for
(int i=
1;i<=n;i++
) lg[i]
=lg[i-1]
+(1<
==i)
;
接下來就是倍增lca
lcalc
a了,按前面說到的我們先把兩個點提到同一高度,再統一開始跳。
int lca
(int x,int y)
}return f[x][0
];//返回父節點
}
ac**
#include
#include
#include
#include
#include
using namespace std;
int n,m,s,x,y,k,h[
500010
],lg[
500010
],dep[
500010
],f[
500010][
22];struct ca[
1000010];
void
add(int x,int y)
void
dfs(int x,int fa)
int lca
(int x,int y)
}return f[x][0
];}int main()
for(int i=
1;i<=n;i++
) lg[i]
=lg[i-1]
+(1<
==i)
;dfs
(s,0);
for(int i=
1;i<=m;i++
)}
洛谷P3379 模板 最近公共祖先(LCA)
題目描述 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入輸出格式 輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩...
洛谷 P3379 模板 最近公共祖先(LCA)
如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...
洛谷 P3379 最近公共祖先(LCA) 模板
如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問a結點和b...