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

2022-08-15 14:42:20 字數 2139 閱讀 2644

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

輸入格式:

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

用tarjan寫的,第一次用讀入優化

異或運算很巧妙,但是要注意cnt要從1開始

find函式也要優化,相比起while,這裡可以一次讓所有父親都找到祖先

#include#include

#define n 500000+10

using

namespace

std;

struct queq[n<<1

];struct edgeg[n<<1

];int n,m,root,cnt=1

,tot,f[n],headq[n],headg[n],v[n];

void read(int &x)

while(s>='

0' && s<='9')

x*=f;

}int find(int a)

void addg(int a,int

b);headg[a]=tot;

}void addq(int a,int

b);headq[a]=cnt;

}void dfs(int

x)

for(int i=headq[x];i;i=q[i].next)

if(v[q[i].to])q[i^1].lca=q[i].lca=find(q[i].to);

}int

main()

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

dfs(root);

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

%d\n

",q[i<<1

].lca);

return0;

}

倍增

#include#include

#include

#include

#include

#include

#define n 500000+5

using

namespace

std;

struct edgea[n<<1

];int head[n],cnt=1,n,m,s,d[n],p[n][21

];void add(int x,int y)

intread()

while(s<='

9' && s>='0')

return x*f;

}void dfs(int x,int

fa)int lca(int x,int

y)int

main()

dfs(s,0);

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

return0;

}

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

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

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

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

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

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