deg其實應該寫成depth吧,存的是每個結點的深度,dfs的過程是為了處理出每個結點的深度,用遞推式計算出fa[u][i],其中f[u][i]表示u的第2^i個祖先;
基本思想是:
d[i] 表示 i節點的深度, p[i,j] 表示 i 的 2^j 倍祖先
那麼就有乙個遞推式子 p[i,j]=p[p[i,j-1],j-1]
這樣子乙個o(nlogn)的預處理求出每個節點的 2^k 的祖先
然後對於每乙個詢問的點對a, b的最近公共祖先就是:
先判斷是否 d[x] < d[y] ,如果是的話就交換一下(保證 x 的深度大於 y 的深度)
然後把 x 調到與 y 同深度, 同深度以後再把a, b 同時往上調,調到有乙個最小的j
滿足p[x,j]!=p[y,j] (x,y是在不斷更新的), 最後再把(x,y)往上調 (x=p[x,0], y=p[y,0])
乙個乙個向上調直到x = y, 這時 x或y 就是他們的最近公共祖先
#include #include #include #include #include #include using namespace std;
const int maxn=200020;
int head[maxn],tol,deg[maxn],fa[maxn][23];
struct node
edge[20*maxn];
void add(int u,int v)
void dfs(int u,int pre)
}int lca(int x,int y)
int main()
dfs(1,1);
// for(i=1;i<=n;i++)cout<>i>>j;
cout<
倍增LCA模板
注意!本篇題解不適合初學lca的同學學習,因為我講的很爛很不清楚。倍增,顧名思義,就是成倍增加的意思。我們知道,任何乙個數字都可以表示成二進位制。那麼對於一條長度為n的鏈,我們總是可以跳大概logn次到達最後。對於鏈上任意一點,我們都可以在大概logn的複雜度下詢問到,其實倍增的思路就是二分,和快速...
POJ 1330(LCA 倍增法模板)
題意 q次詢問求兩個點u,v的lca 思路 lca模板題,首先找一下樹的根,然後dfs預處理求lca u,v ac 1 include2 include3 include4 include5 include 6 include 7 include8 include9 include10 using ...
模板 LCA 最近公共祖先 倍增法
2019 11 07 09 25 45 c.樹之呼吸 叄之型 樹上兩點路徑長度 time limit 1000 ms memory limit 32768 k total submit 7 4 users total accepted 2 2 users special judge no descr...