最近公共祖先 学习笔记
概念
一棵有根树,求两个点的最近公共祖先。
方法
1. 倍增法:
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; k--) if(fa[x][k]!=fa[y][k]) x=fa[x][k],y=fa[y][k]; return fa[x][0]; }
2. dfs 序求 lca:
int get(int x,int y) {return dfn[x]<dfn[y]?x:y;} void dfs(int x,int fa) { st[dfn[x]=++cnt][0]=fa; st[1][1]=fa; for(auto y:e[x]) if(y!=fa) dfs(y,x); } void build_st() { int k=__lg(n); for(int i=1; i<=k; i++) for(int j=1; j+(1<<i)-1<=n; j++) st[j][i]=get(st[j][i-1],st[j+(1<<(i-1))][i-1]); } int lca(int x,int y) { if(x==y) return x; if((x=dfn[x])>(y=dfn[y])) swap(x,y); int k=__lg(y-x++); return get(st[x][k],st[y-(1<<k)+1][k]); }
3. 树剖求 lca:
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; }
本文作者:lgh_2009
本文链接:https://www.cnblogs.com/lgh-blog/p/18133844
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步