模板 最近公共祖先(LCA)

2021-08-06 07:38:28 字數 2773 閱讀 8177

題自洛谷

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

輸入格式:

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

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

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

輸出格式:

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

輸入樣例#1:

5 5 4

3 1

2 4

5 1

1 4

2 4

3 2

3 5

1 2

4 5輸出樣例#1:

4 4

1 4

4時空限制: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

lca的兩種常見演算法就是樹上倍增和tarjan

(乙個直接出答案乙個是最後一起出答案)

這裡都提供一下吧,但是樹上倍增的**不一定對(洛谷上只有30分)

看了下別人的題解說是卡常,但是懶得去改了

const int m=2000005,n=1000005; //資料要多開一倍

int fa[n],head[n],qhead[n],vis[n];

struct edgeedge[n];

struct qedgeq[m];

intread()

return sum;

}int cnt;

void add(int

x,inty)

void aadd(int

x,int

y,int z)

int find(int

x)void unity(int

x,int

y)void tarjan(int

x) }

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

}vis[x]=2;

}int main()

fa[n]=n;

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

tarjan(s);

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

printf("%d\n",q[i*2].ans);

return

0;}

#include

#include

#include

#include

using

namespace

std;

struct nodee[1000005];

int lca[30][600005],deep[600005],h[1000005];

int n,m,t,root;

void add(int u,int v)

int read()

return sum;

}void dfs(int n,int f,int d)

}void init()

}}int lca(int x,int y)

if(x==y) return x;

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

}return lca[0][x];

}int main()

return

0;}

還是要用bfs初始化好一些啊

畢竟時間上bfs還是保守一點的,這次倍增也能過洛谷所有點了

下面貼**

#include

#include

#include

#include

using namespace std;

struct nodee[1000005];

int lca[500005][25],deep[600005],h[500005],q[500005];

bool vis[500005];

int n,m,t,root;

void add(int u,int v)

intread()

return sum;

}void bfs()}}

}int lca(int

x,int

y) return lca[x][0];

}int main()

bfs();

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

return

0;}

模板 lca 最近公共祖先

lca hljs cpp include include using namespace std const int maxn 500001 int n,m,gen,x,y struct edgeedge 2 maxn int deep maxn fa maxn 20 deep記錄每個點的深度,fa...

最近公共祖先 LCA 模板

lca即最近公共祖先,是指 在有根樹中,找出某兩個結點u和v最近的公共祖先。時間複雜度o nlogn m n 步驟 1.將樹看作乙個無向圖,從根節點開始深搜,得到乙個遍歷序列。2.在x y區間中利用rmq演算法找到深度最小返回其下標。可以上洛谷找模板題測試 include include inclu...

最近公共祖先模板(LCA)

我們用鏈式前向星存樹。int head n 1 nex n 1 to n 1 tot 0 void add int a,int b 如果我們用fa x i 表示x的第i級祖先,那麼對時間 空間的複雜度都要求很高,資料稍微大一點顯然不行。所以我們用fa x i 表示x的第1 我們首先dfs去把整棵樹都...