倍增 LCA
预处理复杂度,查询复杂度。
主要思想是倍增,通过预处理出夫亲的倍增数组实现快速求LCA
1 的父节点取 0 是为了方便树上差分,1 的深度设置得比 0 大是为了防止在求LCA时跳到0.
挺好理解的。
#include<bits/stdc++.h>
using namespace std;
#define file(a) freopen(#a".in","r",stdin),freopen(#a".out","w",stdout);
int n,m,s;
vector<int>head,nxt,to;
void add(int u,int v)
{
nxt.push_back(head[u]);
head[u]=to.size();
to.push_back(v);
}
int f[500010][21],dep[500010];
void dfs1(int x,int fa)
{
f[x][0]=fa;dep[x]=dep[fa]+1;
for(int i=0;i<=19;++i)
{
f[x][i+1]=f[f[x][i]][i];
}
for(int i=head[x];i!=-1;i=nxt[i])
{
if(fa==to[i]) continue;
dfs1(to[i],x);
}
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;--i)
{
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
}
if(x==y) return x;
for(int i=20;i>=0;--i)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
head.resize(n+1,-1);
for(int i=1;i<=n-1;++i)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs1(s,0);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具