前言
有的地方说用DFS序求LCA,这是不对的,DFS序求不了LCA,用来求LCA的是欧拉环游序。
O(1)的最近公共祖先
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
int n,m,s;
vector<vector<int>> a;
int deep[500005];
int fa[500005];
void dfs1(int u) {
deep[u]=deep[fa[u]]+1;
for(auto&v:a[u])
if(v^fa[u])
fa[v]=u,dfs1(v);
}
vector<int> Eln;//欧拉序
int stp[500005];
void dfs2(int u) {
stp[u]=Eln.size();
Eln.push_back(u);
for(auto&v:a[u])
if(fa[u]^v)
dfs2(v),Eln.push_back(u);
}
int f[25][1000005];
int K;
int main() {
Eln.push_back(0);
cin>>n>>m>>s;
a.resize(1+n);
for(int i=1;i<n;i++) {
int u,v;
cin>>u>>v;
a[u].push_back(v);
a[v].push_back(u);
}
dfs1(s);
dfs2(s);
K=Eln.size()-1;
for(int i=1;i<=K;i++) deep[f[0][i]=Eln[i]];
for(int k=1;k<25;k++)
for(int i=1;i+(1<<k)-1<=K;i++)
if(deep[f[k-1][i]]<=deep[f[k-1][i+(1<<k-1)]])
f[k][i]=f[k-1][i];
else
f[k][i]=f[k-1][i+(1<<k-1)];
while(m--) {
int x,y;
cin>>x>>y;
x=stp[x];
y=stp[y];
if(x>y) swap(x,y);
int k=log2(y-x+1);
int a=f[k][x],b=f[k][y-(1<<k)+1];
if(deep[a]<=deep[b])
cout<<a<<endl;
else
cout<<b<<endl;
}
return 0;
}
- 主要注意倍增边界
- 然后并没什么细节