【题目描述】
给定一棵 n� 个点的树,Q� 个询问,每次询问点 x� 到点 y� 两点之间的距离。
【输入】
第一行一个正整数 n�,表示这棵树有 n� 个节点;
接下来 n−1�−1 行,每行两个整数 x,y�,�表示 x,y�,� 之间有一条连边;
然后一个整数 Q�,表示有 Q� 个询问;
接下来 Q� 行每行两个整数 x,y�,� 表示询问 x� 到 y� 的距离。
【输出】
输出 Q� 行,每行表示每个询问的答案。
【输入样例】
6
1 2
1 3
2 4
2 5
3 6
2
2 6
5 6
【输出样例】
3
4
【提示】
数据范围与提示:
对于全部数据,1≤n≤105,1≤x,y≤n
AC代码,十分简单易懂:
#include<bits/stdc++.h>
using namespace std;
int f[1001000][30];
int n,q,x,y,cnt,ans;
int lg[1001000],dep[1001000],head[1001000];
struct node{
int v,n;
}t[1001000];
inline int read(){
char c;
int x=0,f=1;
c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
inline void add(int u,int v){
t[++cnt].v=v;
t[cnt].n=head[u];
head[u]=cnt;
}
inline void dfs(int u,int fa){
dep[u]=dep[fa]+1,f[u][0]=fa;
for(int i=1;i<=lg[dep[u]];i++)f[u][i]=f[f[u][i-1]][i-1];
for(int i=head[u];i;i=t[i].n)
if(t[i].v!=fa)dfs(t[i].v,u);
}
inline int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])x=f[x][lg[dep[x]-dep[y]]-1];
if(x==y)return x;
for(int i=lg[dep[x]]-1;i>=0;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int main(){
n=read();
for(int i=1;i<=n;i++)lg[i]=lg[i-1]+(1<<lg[i-1]==i);
for(int i=1;i<n;i++){
x=read(),y=read();
add(x,y),add(y,x);
}
dfs(1,0);
q=read();
for(int i=1;i<=q;i++){
x=read(),y=read();
ans=dep[x]+dep[y]-2*dep[lca(x,y)];
cout<<ans<<"\n";
}
return 0;
}
OK呀,看在我发题解的份上,给个关注再走吧~~~