問題描述
給出一棵有n(編號1到n)個節點的有根樹,求出指定節點對的最近公共祖先!
對於樹中節點x而言,從根節點到達x的這一條路徑中經過的所有節點,都稱為x的祖先。
如上圖所表示的樹中, 根節點為8。8、4、10、16都是12的祖先。對於6和12這對節點而言,從6出發往上朝根走和從12出發往上朝根走的兩條路徑最早交匯的地點是4號節點,因此4號點是6和12的最近公共祖先。
同理,11和9的最近公共祖先是8; 10和3的最近公共祖先是10;2和7的最近公共祖先是4…
輸入格式
第一行,乙個整數n。表示樹中節點總數
接下來n-1行,每行兩個整數x和y,表示x是y的父親。
接下來一行,乙個整數m,表示詢問的總數
接下來m行,每行兩個整數a和b,表示詢問a和b的最近公共祖先。
輸出格式
m行,每行乙個整數,表示對應詢問的答案。
大概思路:用dep來標記樹的深度,fa[v][k]來標記v點向上2^k
步驟:1.dfs來確定層數,將x,y移到同一水平線;
2.將x,y同時向上移,如果x==y就return x;
不說了,直接看**
**:
#include
using
namespace std;
int last[
10010
],next[
10010
],end[
10010
],n,m,x,y,z,dep[
10010
],fa[
10010][
10010];
void
dfs(
int x)
i=last[x]
;while
(i)}
intlca
(int u,
int v)
s=ceil
(log2
(dep[u]))
;for
(i=s;i>=
0;i--)}
return fa[u][0
];//最近公共祖先的上面的結點都是公共祖先
}int
main()
for(
int i=
1;i<=n;i++)}
for(
int i=
1;i<=m;i++
)return0;
}
好啦,差不多就是這樣啦,ღ( ´・ᴗ・` )比心 ~
最近公共祖先 LCA 最近公共祖先
直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...
最近公共祖先 最近公共祖先(LCA)
如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...
C 最近公共祖先 LCA
例題 對於有根樹t的兩個結點u v,最近公共祖先lca t,u,v 表示乙個結點x,滿足x是u v的祖先且x的深度盡可能大。紅色的都是是a和b的公共祖先,但只有最近的c才是最近公共祖先。lca問題是樹上的乙個經典問題,在很多方面有著廣泛的應用,比如求lcp 最長公共字首 接下來我們就來介紹他的幾種演...