注意点:
要倒序,否则无法刚好二进制拼凑
设置哨兵,0的深度为0,且超过树的根节点的值为=0

#include<iostream>
#include<queue>
#include<map>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=5e5+10;
const int inf=0x3f3f3f3f;
int root;
int idx,h[N],e[N],ne[N];
int fa[N][16];
int depth[N];
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void bfs(int root){
queue<int> q;
memset(depth,0x3f,sizeof depth);
depth[0]=0,depth[root]=1;
q.push(root);
while(q.size()){
int t=q.front();
q.pop();
int i;
for(i=h[t];i!=-1;i=ne[i]){
int j=e[i];
if(depth[j]>depth[t]+1){
depth[j]=depth[t]+1;
q.push(j);
fa[j][0]=t;
for(int k=1;k<=15;k++){
fa[j][k]=fa[fa[j][k-1]][k-1];
}
}
}
}
}
int lca(int x,int y){
if(depth[x]<depth[y])
swap(x,y);
int i;
for(i=15;i>=0;i--){
if(depth[fa[x][i]]>=depth[y])
x=fa[x][i];
}
if(x==y)
return x;
for(i=15;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 n,m;
cin>>n;
memset(h,-1,sizeof h);
int i;
int a,b;
for(i=1;i<=n;i++){
scanf("%d%d",&a,&b);
if(b==-1){
root=a;
}
else{
add(a,b);
add(b,a);
}
}
cin>>m;
bfs(root);
while(m--){
int x,y;
cin>>x>>y;
int p=lca(x,y);
if(p==x)
cout<<1<<endl;
else if(p==y)
cout<<2<<endl;
else
cout<<0<<endl;
}
return 0;
}
来源:https://www.cnblogs.com/ctyakwf/p/12484397.html
