一个一个向上调直到x = y, 这时 x或y 就是他们的最近公共祖先
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn=200020; int head[maxn],tol,deg[maxn],fa[maxn][23]; struct node { int next,to; }edge[20*maxn]; void add(int u,int v) { edge[tol].to=v; edge[tol].next=head[u]; head[u]=tol++; } void dfs(int u,int pre) { deg[u]=deg[pre]+1; fa[u][0]=pre; for(int i=1;i<23;i++)fa[u][i]=fa[fa[u][i-1]][i-1]; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v==pre)continue; dfs(v,u); } } int lca(int x,int y) { if(deg[x]<deg[y])swap(x,y); for(int i=0;i<22;i++)if((deg[x]-deg[y])&(1<<i))x=fa[x][i]; if(x==y)return x; for(int i=22;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; return fa[x][0]; } int main() { int i,j,k,m,n; // freopen("data.in","r",stdin); // freopen("data.out","w",stdout); while(cin>>n>>m) { memset(head,-1,sizeof(head));tol=0; for(i=1;i<n;i++) { cin>>j>>k; add(j,k); add(k,j); } dfs(1,1); // for(i=1;i<=n;i++)cout<<deg[i]<<" ";cout<<endl; while(m--) { cin>>i>>j; cout<<lca(i,j)<<endl; } } return 0; }