倍增法
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000010;
int n,m,s;
int h[maxn],nxt[maxn],to[maxn],tot;
int Log[maxn];
int dep[maxn];
int dis[maxn];
int fa[maxn][20];
void add(int x,int y)
{
tot++;
to[tot]=y;
nxt[tot]=h[x];
h[x]=tot;
}
void llog(){for (int i=2;i<=n;i++) Log[i]=Log[i>>1]+1;}
void dfs(int now,int f)
{
dep[now]=dep[f]+1;
fa[now][0]=f;
for (int i=1;i<=19;i++)
{
fa[now][i]=fa[fa[now][i-1]][i-1];
}
for (int i=h[now];i;i=nxt[i])
{
int y=to[i];
if (y==f) continue;
dis[y]=dis[now]+1;
dfs(y,now);
}
}
int lca(int x,int y)
{
if (dep[x]>dep[y]) swap(x,y);
int d=dep[y]-dep[x];
for (int i=Log[d];i>=0;i--)
{
if (d>>i&1) y=fa[y][i];
}
if (x == y) return x;
for (int i=Log[dep[x]];i>=0;i--)
{
if (fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
int main()
{
cin >> n >> m >> s;
llog();
for (int i=1;i<=n-1;i++)
{
int x,y;
cin >> x >> y;
add(x,y);
add(y,x);
}
dfs(s,s);
while (m--)
{
int x,y;
cin >> x >> y;
// int d=dis[x]+dis[y]-dis[lca(x,y)]*2;
// cout << d << endl;
cout << lca(x,y) << endl;
}
return 0;
}
重剖法
struct Tree_Line_Pow_Divide_to_Lca
{
int fa[maxn],son[maxn],top[maxn],dep[maxn],siz[maxn];
int dfn[maxn],rnk[maxn],cnt;
void dfs1(int x)
{
son[x]=-1;siz[x]=1;
for (int i=h[x];i;i=nxt[i])
{
int y=to[i];
if (dep[y]) continue;
dep[y]=dep[x]+1;
fa[y]=x;
dfs1(y);
siz[x]+=siz[y];
if (son[x] == -1 || siz[y]>siz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int t)
{
top[x]=t;
cnt++;
dfn[x]=cnt;rnk[cnt]=x;
if (son[x] == -1) return;
dfs2(son[x],t);
for (int i=h[x];i;i=nxt[i])
{
int y=to[i];
if (y == son[x] || y == fa[x]) continue;
dfs2(y,y);
}
}
int lca(int x,int y)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
}T;
点击查看代码
#include<bits/stdc++.h>
#define Honkai ios::sync_with_stdio(0);
#define StarRail cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
const int maxn=1e6+10;
int n,m,s;
int h[maxn],to[maxn],nxt[maxn],tot;
int fa[maxn],son[maxn],top[maxn],dep[maxn],siz[maxn];
int dfn[maxn],rnk[maxn],cnt;
void add(int x,int y) {tot++;to[tot]=y;nxt[tot]=h[x];h[x]=tot;}
void dfs1(int x)
{
son[x]=-1;siz[x]=1;
for (int i=h[x];i;i=nxt[i])
{
int y=to[i];
if (dep[y]) continue;
dep[y]=dep[x]+1;
fa[y]=x;
dfs1(y);
siz[x]+=siz[y];
if (son[x] == -1 || siz[y]>siz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int t)
{
top[x]=t;
cnt++;
dfn[x]=cnt;rnk[cnt]=x;
if (son[x] == -1) return;
dfs2(son[x],t);
for (int i=h[x];i;i=nxt[i])
{
int y=to[i];
if (y == son[x] || y == fa[x]) continue;
dfs2(y,y);
}
}
int lca(int x,int y)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int main()
{
Honkai StarRail
cin >> n >> m >> s;
for (int i=1;i<n;i++)
{
int x,y;
cin >> x >> y;
add(x,y);add(y,x);
}
dep[s]=1;
dfs1(s);dfs2(s,s);
while (m--)
{
int l,r;
cin >> l >> r;
cout << lca(l,r) << endl;
}
return 0;
}