题目来源
洛谷P3379【模板】最近公共祖先(LCA)
https://daniu.luogu.org/problem/show?pid=3379
思路
LUO树剖
代码(C++)
#include <cstdio>
#include <bitset>
#define N 500010
#define M 1000010
using namespace std;
int n,m,s,u,v,w,x,y,cnt=0,t[N]; bitset<N> g;
int he[N],en[M],ne[M],si[N],hs[N],fa[N],de[N];
inline void add();
inline int read();
void dfs2(int pos,int top);
inline int lca(int x,int y);
void dfs1(int pos,int depth);
int main()
{
n=read(); m=read(); s=read();
for(int i=1;i<n;++i)
u=read(),v=read(),add();
dfs1(s,1); g=0; dfs2(s,s);
for(int i=1;i<=m;++i)
{
x=read(); y=read();
printf("%d\n",lca(x,y));
}
return 0;
}
inline int lca(int x,int y)
{
while(t[x]!=t[y])
{
if(de[t[x]]<de[t[y]]){int z=x; x=y; y=z;}
x=fa[t[x]];
}
if(de[x]>de[y]){int z=x; x=y; y=z;}
return x;
}
void dfs2(int pos,int top)
{
g[pos]=1; t[pos]=top;
if(hs[pos])
dfs2(hs[pos],top);
for(int k=he[pos];k;k=ne[k])
if(!g[en[k]])
dfs2(en[k],en[k]);
return ;
}
void dfs1(int pos,int depth)
{
g[pos]=1; si[pos]=1; de[pos]=depth;
for(int k=he[pos];k;k=ne[k])
if(!g[en[k]])
{
dfs1(en[k],depth+1);
fa[en[k]]=pos;
si[pos]+=si[en[k]];
if(si[en[k]]>si[hs[pos]])
hs[pos]=en[k];
}
return ;
}
inline void add()
{
en[++cnt]=v; ne[cnt]=he[u]; he[u]=cnt;
en[++cnt]=u; ne[cnt]=he[v]; he[v]=cnt;
}
inline int read()
{
char x=getchar(); int num=0;
while(!(x>=48&&x<=57))
x=getchar();
while(x>=48&&x<=57)
num=num*10+x-48,x=getchar();
return num;
}