模板 最近公共祖先 LCA
洛谷 P3379
倍增算法
\(dep_u\) 求u的深度 , 最低为1
\(fa_{u,i}\)为u向上跳\(2^i\)层的祖先结点 , i = 0,1,2,3...
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long int
inline int read() {
int ans = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
ans = ans * 10 + ch - '0';
ch = getchar();
}
return ans * f;
}
const int N = 5e5+10;
int fa[N][20];
int dep[N];
vector<int> v[N];
void dfs(int u,int father) {
dep[u] = dep[father] +1;
fa[u][0] = father;
for (int i = 1; i<= 19; i++) {
fa[u][i] = fa[fa[u][i-1]][i-1];
}
for (auto e: v[u]) {
if (e==father) continue;
dfs(e,u);
}
}
int lca(int u,int v) {
if (dep[u] <dep[v])swap(u,v);
for (int i = 19; i>= 0; i--) {
if (dep[fa[u][i]] >= dep[v]) {
u = fa[u][i];
}
}
if (u==v) return u;
for (int i = 19 ; i>= 0; i--) {
if (fa[u][i]!= fa[v][i]) {
u = fa[u][i],v = fa[v][i];
}
}
return fa[u][0];
}
signed main() {
int n=read(),m=read(),s=read();
for (int i = 1; i< n;i++) {
int x=read(),y=read();
v[y].push_back(x);
v[x].push_back(y);
}
dfs(s,0);
for (int i = 1;i<=m;i++) {
int a=read(),b=read();
cout<<lca(a,b)<<"\n";
}
return 0;
}

浙公网安备 33010602011771号