倍增lca
// Problem: P3379 【模板】最近公共祖先(LCA) // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P3379 // Memory Limit: 512 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; const int mn=500005; int n,m,s; int d[mn],f[mn][21];//depth,f[i][j]表示i向上跳pow(2,j)次到达的点 vector<int> v[mn]; void dfs(int x,int y) { f[x][0]=y;//跳一次就是父亲 d[x]=d[y]+1; for(int i=1;i<=20;i++) { f[x][i]=f[f[x][i-1]][i-1];//跳pow(2,j-1)次到的点跳pow(2,j-1)次就是跳了pow(2,j)次 } for(int i=0;i<v[x].size();i++) { if(v[x][i]!=y) { dfs(v[x][i],x); } } } int lca(int x,int y) { if(d[x]<d[y]) { swap(x,y); } int a=d[x]-d[y]; for(int i=0;i<=20;i++) { if((a>>i)&1)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() { cin>>n>>m>>s; int x,y; for(int i=1;i<n;i++) { cin>>x>>y; v[x].push_back(y); v[y].push_back(x); } dfs(s,0); while(m--) { cin>>x>>y; cout<<lca(x,y)<<'\n'; } return 0; }
本文作者:stawalr
本文链接:https://www.cnblogs.com/ikusiad/p/18705295
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步