陳鋒老師講到的倍增lca的另類做法。
眾所周知,可以利用利用dfs序判斷乙個點y是否在點x的子樹中(不再贅述)。
於是在尋找x和y的lca的時候,只需要讓深度小的那個點(y)往上倍增爬,直到y的父親是x的祖先。
這個原理上比傳統演算法快了一倍,但是占用了較多的記憶體。
#include #include#include
#include
#include
#include
#include
#include
using
namespace
std;
#define reg register
#define ll long longinline ll read()
#define mkp make_pair
#define pii pairnamespace
brimon
ed[n
<<1
];int
head[n], cnt;
inline
void add(int x, int
y) ;
head[x] =cnt;
}int fa[n][21
], dep[n];
intin[n], out
[n], dfsc;
bool isancestor(int x, int y) //
x是不是y的祖先
inline
int lca(int x, int
y) void dfs(int
x)
out[x] = ++dfsc;
}signed main()
dep[root] = 1
; dfs(root);
while(m--) printf("
%d\n
", lca(read(), read()));
return0;
}}signed main()
SCU 3365 學習 LCA 的倍增做法
第一次接觸lca,是在 scu 3365 模板題,當時我是用 disjkstra 加記憶做的,還不會 lca。後來學習 tarjan 演算法,其實還是深搜,當時處理並記錄,tarjan 用來寫 hdu 2586 還是過得去,但是在 scu 3365 卻一直超時,可能 tarjan 演算法在某些資料上...
LCA的倍增演算法
lca,即樹上兩點之間的公共祖先,求這樣乙個公共祖先有很多種方法 每次將深度大的點往上移動,直至二者相遇 在o 2n 預處理重鏈之後,每次就將深度大的沿重鏈向上,直至二者在一條鏈上 先記錄所有的詢問,對樹進行一次dfs,對於搜尋到的點u,先將點u往下搜,再將點u與父節點所在集合合併,之後對於它的所有...
LCA的倍增演算法
對於兩個節點的lca,根據兩個節點的關係分為一下兩種 一 其中一方是另一方的祖先 那u和v的公共祖先就是是祖先的那一方 二 雙方都不是對方的祖先 u和v的祖先x的深度比u和v小,我們先找出u和v中深度較大的乙個,然後讓其向上跳,直到兩個節點的深度相同,當深度相同時,兩個節點開始同時往上跳,直到兩個節...