入門者筆記 LCA(鏈式前向星)

2021-09-24 05:18:36 字數 1716 閱讀 7826

lca(least common ancestors),即最近公共祖先,是指在有根樹中,找出某兩個結點u和v最近的公共祖先。

所謂倍增,就是按2的倍數來增大,也就是跳 1,2,4,8,16,32 …… 不過在這我們不是按從小到大跳,而是從大向小跳,即按……32,16,8,4,2,132,16,8,4,2,1來跳,如果大的跳不過去,再把它調小。這是因為從小開始跳,可能會出現「悔棋」的現象。拿 5 為例,從小向大跳,5≠1+2+4,所以我們還要回溯一步,然後才能得出5=1+45=1+4;而從大向小跳,直接可以得出5=4+1。

原題位址

題目描述

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。

輸入輸出格式

輸入格式:

第一行包含三個正整數n、m、s,分別表示樹的結點個數、詢問的個數和樹根結點的序號。

接下來n-1行每行包含兩個正整數x、y,表示x結點和y結點之間有一條直接連線的邊(資料保證可以構成樹)。

接下來m行每行包含兩個正整數a、b,表示詢問a結點和b結點的最近公共祖先。

輸出格式:

輸出包含m行,每行包含乙個正整數,依次為每乙個詢問的結果。

輸入輸出樣例

輸入樣例#1:

5 5 4

3 12 4

5 11 4

2 43 2

3 51 2

4 5輸出樣例#1:44

144說明

時空限制:1000ms,128m

資料規模:

對於30%的資料:n<=10,m<=10

對於70%的資料:n<=10000,m<=10000

對於100%的資料:n<=500000,m<=500000

**:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

struct yyye[2*

500001];

int depth[

500001

],fa[

500001][

22],lg[

500001

],head[

500001];

int tot;

void

add(

int x,

int y)

void

dfs(

int f,

int fath)

intlca

(int x,

int y)

int n,m,s;

intmain()

dfs(s,0)

;for

(int i=

1;i<=n;i++

) lg[i]

=lg[i-1]

+(1<==i)

;for

(int i=

1;i<=m;i++

)return0;

}

前向星和鏈式前向星

我們首先來看一下什麼是前向星.前向星是一種特殊的邊集陣列,我們把邊集陣列中的每一條邊按照起點從小到大排序,如果起點相同就按照終點從小到大排序,並記錄下以某個點為起點的所有邊在陣列中的起始位置和儲存長度,那麼前向星就構造好了.用len i 來記錄所有以i為起點的邊在陣列中的儲存長度.用head i 記...

前向星和鏈式前向星

前向星 前向星是一種特殊的邊集陣列,我們把邊集陣列中的每一條邊按照起點從小到大排序,如果起點相同就按照終點從小到大排序,並記錄下以某個點為起點的所有邊在陣列中的起始位置。鏈式前向星 鏈式前向星其實就是靜態建立的鄰接表,時間效率為o m 空間效率也為o m 遍歷效率也為o m next表示當前結點的下...

前向星和鏈式前向星

1 前向星 前向星是以儲存邊的方式來儲存圖,先將邊讀入並儲存在連續的陣列中,然後按照邊的起點進行排序,這樣陣列中起點相等的邊就能夠在陣列中進行連續訪問了。它的優點是實現簡單,容易理解,缺點是需要在所有邊都讀入完畢的情況下對所有邊進行一次排序,帶來了時間開銷,實用性也較差,只適合離線演算法。圖一 2 ...