時間限制: 1 sec
記憶體限制: 128 mb
提交: 244
解決: 36
[ 提交][
狀態]給一棵樹, 節點數為n(1 <= n <= 250,000), 和q(0 <= q <= 100,000)個詢問, 對於每個詢問求出所求兩點的最近公共祖先
第一行: 節點數n
以下n行, 第i + 1行: 點i的父親節點father[i] (假定根的父親是0)
下一行為詢問數q
每個詢問包含兩個整數i, j你的程式應按照詢問的次序回答出所求兩點的最近公共祖先
共n行, 第i行: 第i個詢問的答案
12011122
3388
91055 12
12 7
9 12
10 12
12 12
1381012
倍增演算法:主要分兩步。
第一步:將兩個節點"竄"到乙個深度
第二步:兩個節點一起"竄"到他們的lca(最近公共祖先)。
'竄'的操作,如果你每個節點一下,一下,一下的竄,會非常慢。。所以就有了倍增,要一次竄2^n個節點。當然如果過頭了就少竄一點。如果你寫過01
揹包,它的思路和2進製拆包很像。
看起來好像很簡單的樣子》-《**如下(帶注釋)
#include#include#include#include#include#include#includeusing namespace std;
const int maxn=250020;
int n,q;
int g[100][100],ne,root;
int p[maxn][20];//p[i][j]表示i結點的第2^j祖先
int deep[maxn];//i的深度
int use[1000][1000];
void build(int x)//處理樹深度
} void pre()//處理祖先
} return p[a][0];//即正好竄到兩個子樹上,最近祖先為它的j=0的祖先
}int main()
p[1][0]=-1;
deep[1]=1;
build(1);
pre();
for(int i=1;i<=q;i++)
return 0;
}
倍增LCA模板
注意!本篇題解不適合初學lca的同學學習,因為我講的很爛很不清楚。倍增,顧名思義,就是成倍增加的意思。我們知道,任何乙個數字都可以表示成二進位制。那麼對於一條長度為n的鏈,我們總是可以跳大概logn次到達最後。對於鏈上任意一點,我們都可以在大概logn的複雜度下詢問到,其實倍增的思路就是二分,和快速...
LCA倍增法模板
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...
倍增求lca(模板)
定義 lca,最近公共祖先,是指一棵樹上兩個節點的深度最大的公共祖先。也可以理解為兩個節點之間的路徑上深度最小的點。我們這裡用了倍增的方法求了lca。我們的基本的思路就是,用dfs遍歷求出所有點的深度。f i j 陣列用來求的是距離節點i,距離2 j的祖先。可以知道,f i 0 就是它的直接父親。然...