lca演算法:
lca(least common ancestor),是指在一棵樹中,距離兩個點最近的兩者的公共節點。也就是說,在兩個點通往根的道路上,肯定會有公共的節點,我們就是要求找到公共的節點中,深度盡量深的點。還可以表示成另一種說法,就是如果把樹看成是乙個圖,這找到這兩個點中的最短距離。
本文先介紹乙個離線的演算法,就做tarjan演算法。這個演算法是基於並查集和dfs的。dfs的作用,依次對樹中的每乙個節點進行處理。而並查集的作用就是當dfs每訪問完(注意,這裡是訪問完)到乙個點的時候,就通過並查集將這個點,和它的子節點鏈結在一起構成乙個集合,也就是將並查集中的pnt值都指向當前節點。這樣就把樹中的節點分成了若干個的集合,然後就是根據這些集合的情況來對輸入資料來進行處理。
比方說當前訪問到的節點是u,等u處理完之後呢,ancestor[u]就構成了u的集合中的點與u點的lca,而ancestor[fa[u]]就構成了,u的兄弟節點及其兄**樹的集合中點與u的lca,而ancestor[fa[fa[u]]]就構成了u的父親節點的兄弟節點及其兄**樹的集合中的點與u的lca。然後依次類推,這樣就構成了這個lca的離線演算法。
ancestor表示的是當前節點集合的祖先。
int find(int x)
int unite(int a,int b)
void lca(int parent)
vis[parent] = true;
if( parent = first && vis[second] ) //這裡的first和second主要針對的是查詢的每次操作時輸入的兩個數。
ans = ancestor[find(second)] ;
if( parent = second && vis[first] )
ans = ancestor[find(first)];
}
LCA 離線tarjan演算法
對於最近公共祖先問題,我們先來看這樣乙個性質,當兩個節點 u,v 的最近公共祖先是x時,那麼我們可以確定的說,當進行後序遍歷的時候,必然先訪問完x的所有子樹,然後才會返回到x所在的節點。這個性質就是我們使用tarjan演算法解決最近公共祖先問題的核心思想。同時我們會想這個怎麼能夠保證是最近的公共祖先...
LCA的離線演算法Tarjan
總的來說是深度遍歷。以根為節點建立並查集。比如說求p,v的lca。當訪問到p的時候檢查v是否已經訪問過。如果訪問過,那麼他們的lca就是v現在所在的並查集裡面的元素。如果沒有訪問到。那麼等到v訪問到的時候可以操作一下。充分利用了遞迴這個操作,所以不必要儲存以前的東西,自然而然的就將u裡面的所有的子節...
關於LCA的離線演算法 Tarjan
利用並查集優越的時空複雜度,我們可以實現lca問題的o n q 演算法,這裡q表示詢問 的次數。tarjan演算法基於深度優先搜尋的框架,對於新搜尋到的乙個結點,首先建立由這個結點 構成的集合,再對當前結點的每乙個子樹進行搜尋,每搜尋完一棵子樹,則可確定子樹 內的lca詢問都已解決。其他的lca詢問...