洛谷P3379 模板 最近公共祖先(LCA)

2022-06-03 22:18:16 字數 2864 閱讀 1137

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

輸入格式:

第一行包含三個正整數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:

441

44

時空限制:1000ms,128m

資料規模:

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

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

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

樣例說明:

該樹結構如下:

第一次詢問:2、4的最近公共祖先,故為4。

第二次詢問:3、2的最近公共祖先,故為4。

第三次詢問:3、5的最近公共祖先,故為1。

第四次詢問:1、2的最近公共祖先,故為4。

第五次詢問:4、5的最近公共祖先,故為4。

故輸出依次為4、4、1、4、4。

模板題,不解釋了。

#include#include

#include

#include

using

namespace

std;

const

int maxn=500000+5

;inline

intread()

while(ch>='

0'&&ch<='9')

return x*f;

}int

n,m,s,num;

int f[maxn][20

],head[maxn],dep[maxn];

bool

vis[maxn];

struct

node

e[maxn

<<1

];inline

void add(int

from,int

to)inline

void dfs(int x,int

d) }

}inline

int lca(int a,int

b)

int d=dep[a]-dep[b];

for(int i=19;i>=0;i--)

if(d&(1

if(a==b) return

a;

for(int i=19;i>=0;i--)

if(f[a][i]!=f[b][i])

return f[a][0];}

intmain()

dfs(s,1);

for(int j=1;j<=19;j++)

for(int i=1;i<=n;i++)

f[i][j]=f[f[i][j-1]][j-1

];

for(int i=1;i<=m;i++)

return0;

}

view code

#include#include

#include

#include

using

namespace

std;

const

int maxn=500000+5

;inline

intread()

while(ch>='

0'&&ch<='9')

return x*f;

}int

n,m,s,num,qnum;

int father[maxn],head[maxn],qhead[maxn],a[maxn][3

];bool

vis[maxn];

struct

node

e[maxn

<<1

];struct

qnode

q[maxn

<<1

];inline

void add(int

from,int

to)inline

void qadd(int

from,int to,int

k)inline

int find(int

x)inline

void merge(int x,int

y)void tarjan(int

x)

for(int i=head[x];i;i=e[i].next)

}}int

main()

for(int i=1;i<=m;i++)

tarjan(s);

for(int i=1;i<=m;i++)

printf(

"%d\n

",a[i][2

]);

return0;

}

view code

還有我補充一下我一直以來的思維誤區:

我原以為一棵樹的根節點變了,兩個節點的最近公共祖先是不會變的。

這是是錯誤的,反例很好舉:

假如兩個幾點的最近公共祖先是根節點,那麼當其中乙個節點變為根節點時,它們的最近公共祖先就變成了現在的根節點。

洛谷P3379 模板 最近公共祖先(LCA)

題目描述 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入輸出格式 輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩...

洛谷 P3379 模板 最近公共祖先(LCA)

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...

洛谷 P3379 最近公共祖先(LCA) 模板

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問a結點和b...