祖孙询问

给定一棵包含 nn 个节点的有根无向树,节点编号互不相同,但不一定是 1∼n。

有 mm 个询问,每个询问给出了一对节点的编号 x 和 y,询问 x 与 y 的祖孙关系。

输入格式

输入第一行包括一个整数 表示节点个数;

接下来 n 行每行一对整数 a 和 b,表示 a 和 b 之间有一条无向边。如果 b 是 −1,那么 a 就是树的根;

第 n+2 行是一个整数 m 表示询问个数;

接下来 m 行,每行两个不同的正整数 x 和 y,表示一个询问。

输出格式

对于每一个询问,若 x 是 y 的祖先则输出 1,若 y 是 x 的祖先则输出 2,否则输出 00。

数据范围

1≤n,m≤4×10^4
1≤每个节点的编号≤4×10^4

输入样例:

10
234 -1
12 234
13 234
14 234
15 234
16 234
17 234
18 234
19 234
233 19
5
234 233
233 12
233 13
233 15
233 19

输出样例:

1
0
0
0
2

思路

lca模板题

代码

#include<bits/stdc++.h>
using namespace std;
const int N=4e4+10;
int n,root,idx,h[N],q[N],dep[N],anc[N][20];
struct eg{
    int v,nex;
}e[N*2];
void add(int u,int v){
    e[idx]={v,h[u]};
    h[u]=idx++;
}
void bfs(){
    int hh=0,tt=0;
    memset(dep,0x3f,sizeof dep);
    q[tt++]=root;
    dep[0]=0;
    dep[root]=1;
    while(hh!=tt){
        int u=q[hh++];
        if(hh==N) hh=0;
        for(int i=h[u];~i;i=e[i].nex){
            int v=e[i].v;
            if(dep[v]>dep[u]+1){
                dep[v]=dep[u]+1;
                q[tt++]=v;
                if(tt==N) tt=0;
                anc[v][0]=u;
                for(int j=1;j<=15;++j)
                    anc[v][j]=anc[anc[v][j-1]][j-1];
                //cout<<v<<" "<<dep[v]<<endl;
            }
        }
    }
}
int lca(int u,int v){
    if(dep[u]<dep[v]) swap(u,v);
    for(int i=15;i>=0;--i){
        if(dep[anc[u][i]]>=dep[v])
            u=anc[u][i];
    }
    if(u==v) return u;
    for(int i=15;i>=0;--i){
        if(anc[u][i]!=anc[v][i]){
            u=anc[u][i];
            v=anc[v][i];
        }
    }
    return anc[u][0];
}
int main(){
    cin>>n;
    memset(h,-1,sizeof h);idx=0;
    for(int i=1;i<=n;++i){
        int a,b;
        scanf("%d%d",&a,&b);
        if(b==-1) root=a;
        else add(a,b),add(b,a);
    }
    bfs();
    int m;
    cin>>m;
    while(m--){
        int a,b;
        scanf("%d%d",&a,&b);
        int t=lca(a,b);
        if(t==a) cout<<"1\n";
        else if(t==b) cout<<"2\n";
        else cout<<0<<endl;
    }
    return 0;
}

posted @ 2020-05-15 14:27  0x4f  阅读(197)  评论(0编辑  收藏  举报