倍增几大用处之一!!!LCA!!!
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #define ll long long using namespace std; const ll maxn=500010; ll n,m,s,x,y,a,b,cnt=0,N; ll f[maxn][30],head[maxn],dept[maxn]; struct Edge{ ll next,to; }cute[maxn<<1];//要建两遍图 数组不要忘记开大一倍 void build(ll x,ll y) { cute[++cnt].next=head[x]; cute[cnt].to=y; head[x]=cnt; } void pre() { for(ll i=1;i<=N;i++) for(ll j=1;j<=n;j++) f[j][i]=f[f[j][i-1]][i-1]; } void dfs(ll x) { for(ll i=head[x];i;i=cute[i].next) { ll y=cute[i].to; if(f[x][0]!=y) { f[y][0]=x; dept[y]=dept[x]+1; dfs(y); } } } ll lca(ll x,ll y) { if(dept[x]>dept[y]) swap(x,y); ll t=dept[y]-dept[x]; for(ll i=N;i>=0;i--) if(t&(1<<i)) y=f[y][i]; if(x==y) return x; for(ll i=N;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("%lld%lld%lld",&n,&m,&s); for(ll i=1;i<=n-1;i++) { scanf("%lld%lld",&x,&y); build(x,y); build(y,x); } N=log2(n); dept[s]=1; f[s][0]=0; dfs(s); pre(); for(ll i=1;i<=m;i++) { scanf("%lld%lld",&a,&b); printf("%lld ",lca(a,b)); } return 0; }