DFS 序 O(1) 求 LCA
更新日志
2025/11/03:开工。思路
查询 \((dfn_u,dfn_v]\) 最小深度的节点的父亲即可。读者自证不难。
代码
const int N=5e5+5,T=20;
int n,m,s;
vec<int> g[N];
int dcnt,dfn[N],dp[N];
int st[N][T],lg[N];
void dfs(int x,int fa){
dp[x]=dp[fa]+1;
dfn[x]=++dcnt,st[dfn[x]][0]=fa;
for(auto y:g[x])if(y!=fa)dfs(y,x);
}
inline int lca(int a,int b){
if(a==b)return a;
a=dfn[a],b=dfn[b];if(a>b)swap(a,b);++a;
int t=lg[b-a+1];
return (dp[st[a][t]]<dp[st[b-(1<<t)+1][t]]?st[a][t]:st[b-(1<<t)+1][t]);
}
inline void Main(){
cin>>n>>m>>s;
rep(i,2,n)lg[i]=lg[i>>1]+1;
repl(i,1,n){
int a,b;cin>>a>>b;
g[a].pub(b),g[b].pub(a);
}
dfs(s,0);
repl(t,1,T)rep(i,1,n-(1<<t)+1)st[i][t]=(dp[st[i][t-1]]<dp[st[i+(1<<t-1)][t-1]]?st[i][t-1]:st[i+(1<<t-1)][t-1]);
rep(i,1,m){
int a,b;cin>>a>>b;
put(lca(a,b));
}
}

浙公网安备 33010602011771号