最近公共祖先(LCA)(RMQ)
【模板】最近公共祖先(LCA)(RMQ)
题目描述
如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。
输入格式
第一行包含三个正整数
接下来
接下来
输出格式
输出包含
样例 #1
样例输入 #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
提示
对于
对于
对于
样例说明:
该树结构如下:
第一次询问:
第二次询问:
第三次询问:
第四次询问:
第五次询问:
故输出依次为
思路
我们已经学会了
欧拉序
上面这棵树的欧拉序是
初始化
我们已经把一颗树变成了数列,然后就是
定义:数组
if(de[f[i][j-1]]<de[f[i+2^{j-1}][j-1]])f[i][j]=f[i][j-1]//de[i]表示i的深度
else f[i][j]=f[i+2^{j-1}][j-1]
查询
如果要查
int l=first[x],r=first[y];//first[i]表示i第一次在欧拉序里出现的位置
if(r<l)swap(l,r);
int k=log2(r-l+1);
return (de[f[l][k]]<de[f[r-(1<<k)+1][k]])?f[l][k]:f[r-(1<<k)+1][k];
完整代码:
提示:数组开大点,欧拉序很长。
#include<cstdio>
#include<cmath>
#define MAXN (5000000+100)
int ver[MAXN*2],next[MAXN*2],head[MAXN*2],bdfs[MAXN*5],de[MAXN],first[MAXN],f[MAXN][100],tot,n,m,s,cnt;
void add(int x,int y){
ver[++tot]=y;
next[tot]=head[x];
head[x]=tot;
}
void swap(int& a,int& b){
int temp=a;
a=b;
b=temp;
}
void dfs(int i,int father,int depth){//dfs求欧拉序和深度
bdfs[++cnt]=i;
de[i]=depth;
if(!first[i])first[i]=cnt;
for(int j=head[i];j;j=next[j]){
if(ver[j]!=father){
dfs(ver[j],i,depth+1);
bdfs[++cnt]=i;
}
}
}
void init_st(){//初始化st表
for(int i=cnt;i>=1;i--){
f[i][0]=bdfs[i];
for(int j=1;j<20;j++){
if((i+(1<<(j-1)))>cnt){break;}
f[i][j]=de[f[i][j-1]]<de[f[i+(1<<(j-1))][j-1]]?f[i][j-1]:f[i+(1<<(j-1))][j-1];//状态转移方程
}
}
}
int getlca(int x,int y){//查询
int l=first[x],r=first[y];
if(r<l)swap(l,r);
int k=log2(r-l+1);
return (de[f[l][k]]<de[f[r-(1<<k)+1][k]])?f[l][k]:f[r-(1<<k)+1][k];
}
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=n-1;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(s,0,1);
init_st();
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",getlca(x,y));
}
return 0;
}
本文来自博客园,作者:maniubi,转载请注明原文链接:https://www.cnblogs.com/maniubi/p/16434207.html,orz
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效