常用的求 lca 的演算法有:ta
rjan
/ df
s+st
/ 倍增o(
logn
) ~ o(
nlog
n)之間。 ta
rjan
是 離線 演算法。顧名思義,就是在一次遍歷中把所有詢問一次性解決,所以其時間複雜度是 o(
n+q)
。
利用了 df一開始我們輸入的是一張圖,沒有任何父親兒子的關係。s 和並查集的思想,祖先回溯記錄為上乙個,如果已經某一點遍歷過了就 fi
nd()
祖先。
流程:
任選乙個點為根節點,從根節點開始。
遍歷該點
u 所有子節點
v,並標記這些子節點
v 已被訪問過。
若是 v
還有子節點,返回 2,否則下一步。
合併 v
到 u上。
尋找與當前點
v (當前點即是需要合併的點) 有詢問關係的點 x。
若是這個點
x 已經被訪問過了,則可以確認 v和
x 的最近公共祖先為
x被合併到的父親節點
a 。
注意只有把乙個點的所有子節點都訪問完畢以後再尋找與當前點有詢問關係的點。
luogu p3379 【模板】最近公共祖先(lca)ta
rjan
求 lca
是個離線演算法。
那個 e1[
].nu
m 記錄訪問的次序。
#include
using
namespace
std;
const
int n = 5e5 + 5;
int cnt = 0, cnt1 = 0;
int vis[n], father[n];
int head[n], head1[n];
int ans[n];
struct edge e[n << 1], e1[n << 1];
void add(int x, int y)
void add1(int x, int y, int z)
void make(int n)
int find(int x)
void dfs(int u)
for(int i = head1[u]; i; i = e1[i].next)
}int main()
for(int i = 1; i <= m; i ++)
dfs(s);
for(int i = 1; i <= m; i ++)
printf("%d\n", ans[i]);
return
0;}
LCA離線演算法tarjan
lca演算法 lca least common ancestor 是指在一棵樹中,距離兩個點最近的兩者的公共節點。也就是說,在兩個點通往根的道路上,肯定會有公共的節點,我們就是要求找到公共的節點中,深度盡量深的點。還可以表示成另一種說法,就是如果把樹看成是乙個圖,這找到這兩個點中的最短距離。本文先介...
LCA 離線tarjan演算法
對於最近公共祖先問題,我們先來看這樣乙個性質,當兩個節點 u,v 的最近公共祖先是x時,那麼我們可以確定的說,當進行後序遍歷的時候,必然先訪問完x的所有子樹,然後才會返回到x所在的節點。這個性質就是我們使用tarjan演算法解決最近公共祖先問題的核心思想。同時我們會想這個怎麼能夠保證是最近的公共祖先...
LCA 離線tarjan模板
演算法引入 樹上兩點的最近公共祖先 對於有根樹的兩個結點u,v,最近公共祖先lca t,u,v 表示乙個結點x,滿足x是u,v的祖先且x的深度盡可能大 對於x來說,從u到v的路徑一定經過點x 演算法思想 tarjan lca離線演算法 tarjan演算法基於dfs的框架,對於新搜到的乙個結點,首先建...