最近公共祖先LCA Tarjan演算法

2021-08-13 02:12:11 字數 1335 閱讀 1597

在一棵樹中,兩個結點之間第乙個共同的祖先。

如圖:

結點10和11的公共祖先有1、7、8、⑨四個節點,但是只有⑨是離其最近的,所以只有⑨是lca

同理,3和11的lca即是根節點1。2和4的lca是2。

其實講個道理,我也不知道究竟是不是tarjan演算法,因為網上說這個dfs序離線做法不是tarjan啥的,姑且這麼叫吧。。反正複雜度也是很低

作為oi利器**師–dfs–深度優先搜尋

據說是只要你dfs學得好,你就能一等,你就能拿金

所謂dfs序,就是按照dfs遍歷的順序記錄下點的順序。

再比如,還是上圖為例:

若是我們遍歷的順序是從左到右,則dfs序是這樣的:

有這個例項在,應該可以理解了吧。

既然提到了dfs序的概念,我想很多人已經知道接下來怎麼求lca了

沒錯,就是在兩個結點中找到深度最小的那個結點。

沒有想象中的複雜吧。。這就是演算法的迷人之處呢。

**:

#include

#include

#include

#define maxn 100005

using

namespace

std;

struct nodeedge[maxn];

int c=0,lc,ans,e=0,q,n,m;

int find_p[maxn],dfs_d[maxn],dfs_p[maxn],dfs_w[maxn],head[maxn];

void add(int u,int v,int d)

void dfs_lca(int pre,int now,int deep,int weight)

}c++;//同樣又一次回到了起點

dfs_p[c]=now;

dfs_d[c]=deep;

dfs_w[c]=weight;

find_p[now]=c;//now這個點最後被記錄的位置

return ;

}void lca()

void find_lca(int u,int v)

int main()

lca();

scanf("%d",&q);

for(int i=1;i<=q;i++)

return

0;}

**中使用的資料結構是鍊錶,但是是用陣列模擬的辦法,需要學習這種方法的同學可以去我的另一篇部落格:

祝各位oier武運昌隆!!!

演算法摘記 最近公共祖先LCA Tarjan演算法

在求解最近公共祖先為問題上,用到的是tarjan的思想,從根結點開始形成一棵深搜樹,非常好的處理技巧就是在回溯到結點u的時候,u的子樹已經遍歷,這時候才把u結點放入合併集合中,這樣u結點和所有u的子樹中的結點的最近公共祖先就是u了,u和還未遍歷的所有u的兄弟結點及子樹中的最近公共祖先就是u的父親結點...

最近公共祖先 python 最近公共祖先

lca演算法樸素演算法 也就是我們所說的暴力演算法,大致的思路是從樹根開始,往下迭代,如果當前結點比兩個結點都小,那麼說明要從樹的右子樹中找 相反則從左子樹中查詢 直到找到乙個結點在當前結點的左邊,乙個在右邊,說明當前結點為最近公共祖先,如果乙個結點是另外乙個結點的祖先,那麼返回前面結點的父親結點即...

最近公共祖先 LCA 最近公共祖先

直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...