#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> using namespace std; int n,m,root,k,head[500001],deep[500001],f[500001][21]; struct zhzs { int to,next; }edge[1000001]; inline void add(int u,int v) { edge[++k].to=v; edge[k].next=head[u]; head[u]=k; } void dfs(int t,int baba) { deep[t]=deep[baba]+1; f[t][0]=baba; for(register int i=1;(1<<i)<=deep[t],i<=20;++i)//一定要记住不能超过整个树的祖先 f[t][i]=f[f[t][i-1]][i-1]; for(register int i=head[t];i;i=edge[i].next) if(edge[i].to!=baba) dfs(edge[i].to,t); } int lca(int x,int y) { if(deep[x]<deep[y]) swap(x,y); for(register int i=20;i>=0;--i) if(deep[x]-(1<<i)>=deep[y]) x=f[x][i]; if(x==y) return x; for(register 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() { scanf("%d%d%d",&n,&m,&root); int x,y; for(register int i=1;i<=n-1;++i) { scanf("%d%d",&x,&y); add(x,y); add(y,x);//链式邻接表存边 } dfs(root,0); for(register int i=1;i<=m;++i) { scanf("%d%d",&x,&y); printf("%d\n",lca(x,y)); } return 0; }
链式前向星与lca
最新推荐文章于 2024-08-27 10:08:55 发布