首页 > 代码库 > lca最近公共祖先(st表)
lca最近公共祖先(st表)
大体思路
1.求出每个元素在树中的深度
2.用st表预处理的方法处理出f[i][j],f[i][j]表示元素i上方第2^j行对应的祖先是谁
3.将较深的点向上挪,直到两结点的深度相同
4.深度相同后,祖先可能就在上方,再走几步就到了,于是两个点同时向上移
具体的方法和代码贴在下面 ↓
具体来看
1.求出每个元素在树中的深度
//求每个节点在树中的深度 void dfs(int pos,int pre)//pre是pos的父节点 { for(int i=0;i<v[pos].size;i++)//枚举pos的子节点 { register int t=v[pos][i]; if(t==pre)continue;//防止死循环 f[t][0]=pos;dep[t]=dep[pos]+1; dfs(t,pos);//再从子节点向后枚举 } }
2.用st表预处理的方法处理出f[i][j]
//求f数组(st表预处理) for(int i=1;(1<<i)<=n;i++) for(int j=1;j<=n;j++) f[j][i]=f[f[j][i-1]][i-1]; //f[i][j]表示元素i上方第2^j行对应的祖先是谁
3.先比较a,b两点哪个较深,将较深的点赋值给a
//把a节点变为a,b中较深的一个节点 int query(int a,int b) { if(dep[a]<dep[b])swap(a,b); }
将较深的点向上挪,直到两结点的深度相同
//使a和b在同一个深度上 for(int i=20;i>=0;i--) if(dep[f[a][i]]>=dep[b]) a=f[a][i]; //倒着循环是因为向上走的步数只会越来越小
4.深度相同后,祖先可能就在上方,再走几步就到了,于是两个点同时向上移
//同一深度后,再向上找公共祖先 for(int i=20;i>=0;i--) if(f[a][i]!=f[b][i]) { a=f[a][i]; b=f[b][i]; }
lca最近公共祖先(st表)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。