最近公共祖先問題(LCA)

2021-06-18 13:59:10 字數 810 閱讀 3665

最近公共祖先問題(lca)

(下面的內容來自演算法藝術與資訊學競賽一書)

lca問題:給出乙個有根樹t,對於任意兩個節點u和v,求出 lca(t, u, v).即離根最遠的結點x,使得x同時是u和v的祖先。

從上面的遞推方法,給我們乙個啟示。當l(u)<=l(v)時,可以根據lca(u,v)的答案把所有結點分成若干個等價類,u的子樹上節點v都滿足lca(u,v)=u;u的父親fahter(u)的任何不以u為根的子樹上的結點v都滿足lca(u,v)=father(u);father(fahter(u))的任何不以fahter(u)為根的子樹上節點v都滿足lca(u,v)=fahter(father(u));...........

lca問題的tarjan演算法:用lca(root(t))呼叫下面的過程,演算法將會回答所有的詢問。

//merge():表示把u和v所在的集合合併,u為集合的代表元。find()表示找出集合的代表元。可以看出,在任何時侯乙個集合裡面的元素都形成了一顆樹。

//每處理完一顆子樹就把它並到父親所在的集合中。該演算法執行的是深度優先遍歷,因此對於任何處理過的節點v,v當前所在的集合的代表元就是v和當前處理結點u的lca。

//演算法的巧妙之處在於利用了並查集。使得和當前處理元素u有關的所有詢問都可以立即得出,而不需要一一計算。

void lca(u)

visit[u] = true;

for(q(u)中的每個元素v)

}

最近公共祖先 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,表示詢問...

LCA (最近公共祖先問題)

摘自kiana810學長的講課內容 lca least common ancestors 即最近公共祖先,是指在有根樹中,找出某兩個結點u和v最近的公共祖先 另一種說法,離樹根最遠的公共祖先 眾所周知,兩點在樹上的路徑是唯一的,但是如何快速維護路徑的相關資訊 路徑權值和 路徑邊權最大 最小值等 在解...