【LCA】
LCA最近公共祖先
对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u和v的祖先且x的深度尽可能大。在这里,一个节点也可以是它自己的祖先。-百度百科
先DFS求出每个点的深度,在通过倍增向上爬。预处理,查询
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 +5;
int h[N],ne[N<<1],e[N<<1],fa[N<<1][22],lg[N<<1],dep[N],idx,n,m,s;
inline void add(int x,int y){e[++idx] = y,ne[idx] = h[x];h[x] = idx;}
void dfs(int u,int f)
{
fa[u][0] = f;dep[u] = dep[f] + 1;
for(int i = 1 ; i <= lg[dep[u]] ; i ++)
fa[u][i] = fa[fa[u][i - 1]][i - 1];
for(int i = h[u];i;i = ne[i])
if(e[i] != f)dfs(e[i],u);
}
int lca(int x,int y)
{
if(dep[x] < dep[y])swap(x,y);
while(dep[x] > dep[y])x = fa[x][lg[dep[x] - dep[y]] - 1];
if(x == y )return x;
for(int k = lg[dep[x]] - 1; k >= 0 ; k --)
if(fa[x][k] != fa[y][k])
x = fa[x][k],y = fa[y][k];
return fa[x][0];
}
int main()
{
cin >> n >> m >> s;
for(int x,y,i = 1; i <= n -1 ; i ++ )
{
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
for(int i = 1 ; i <= n ; i ++)
lg[i] = lg[i - 1] + (1 << lg[i - 1] == i );
dfs(s,0);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
}
“风雪越是呼啸,雪莲越是绽放”
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】