LCA学习笔记
LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。
实现
暴力
不说了。
int query(Node t, Node u, Node v) { int left=u.value; int right=v.value; //如果左结点大于右结点则交换 if(left>right)swap(left,right); while(1){ //如果t小于u、v则往t的右子树中查找 if(t.value<left)t=t.right;//如果t大于u、v则往t的左子树中查找 else if(t.value>right)t=t.left; else return t.value; } }
Tarjan
并查集维护祖先。
#include<bits/stdc++.h> #define int long long using namespace std; int n,m,s; struct ask{ int a,b; }; vector<ask>quer[1000100]; vector<int>v[1000100]; int fa[1000001],k[1000001],d[10000001],ans[10000001]; int find(int x){ if(fa[x]==x)return x; else return fa[x]=find(fa[x]); } void tarjan(int x){ k[x]=1; for(auto i:v[x]){ if(k[i])continue; d[i]=d[x]+1; tarjan(i); fa[i]=x; } for(int i=0;i<quer[x].size();i++){ int y=quer[x][i].a,id=quer[x][i].b; if(k[y]==2){ int lca=find(y); ans[id]=lca; } } k[x]=2; } signed main(){ cin>>n>>m>>s; for(int i=0;i<=n;i++)fa[i]=i; for(int i=1;i<n;i++){ int uu,vv; cin>>uu>>vv; v[uu].push_back(vv); v[vv].push_back(uu); } for(int i=1;i<=m;i++){ int uu,vv; cin>>uu>>vv; if(uu==vv)ans[i]=uu; quer[uu].push_back(ask{vv,i}); quer[vv].push_back(ask{uu,i}); } tarjan(s); for(int i=1;i<=m;i++){ cout<<ans[i]<<endl; } return 0; }
倍增
树链剖分
本文作者:ccrui
本文链接:https://www.cnblogs.com/ccr-note/p/LCA-note.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步