题意:
给定一棵 n 个点的树,Q 个询问,每次询问点 x 到点 y两点之间的距离。
分析:
没什么好分析的……
代码:
#include<bits/stdc++.h>
#define N 100009
using namespace std;
int n,q;
int nxt[2*N],to[2*N],head[N],w[N*2],cnt=0;
void add(int x,int y,int z){
nxt[++cnt]=head[x];head[x]=cnt;
to[cnt]=y;w[cnt]=z;
}
int fa[N][25],d[N],dep[N];
void dfs(int u,int fu){
fa[u][0]=fu;
for(int e=head[u];e;e=nxt[e]){
int v=to[e];
if(v==fu) continue;
d[v]=d[u]+1;dep[v]=dep[u]+1;
dfs(v,u);
}
}
int getlca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;--i) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
if(x==y) return x;
for(int i=20;i>=0;--i)
{
if(fa[x][i]!=fa[y][i]){
x=fa[x][i];y=fa[y][i];
}
}
return fa[x][0];
}
int main(){
scanf("%d",&n);
int i,j,k,x,y;
for(i=1;i<n;++i){
scanf("%d%d",&x,&y);
add(x,y,1);
}
d[1]=0;dep[1]=1;
dfs(1,0);
for(j=1;j<=20;++j)
for(i=1;i<=n;++i)
fa[i][j]=fa[fa[i][j-1]][j-1];
scanf("%d",&q);
for(i=1;i<=q;++i){
scanf("%d%d",&x,&y);
int lca=getlca(x,y);
printf("%d\n",d[x]+d[y]-d[lca]*2);
}
return 0;
}