题目解析
已知一棵n个节点的有根树。有m个询问。每个询问给出了一对节点的编号x和y,询问x与y的祖孙关系。
题目解析
L C A LCA LCA即可,随便判断一下
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,root,t;
int k[40005],f[40005][30],dis[40005][30];
vector<int> a[40005];
queue<int> q;
void fun()
{
q.push(root);
k[root]=1;
while(!q.empty())
{
u=q.front(),q.pop();
for(int i=0;i<a[u].size();i++)
{
v=a[u][i];
if(!k[v])
{
k[v]=k[u]+1;
f[v][0]=u;
q.push(v);
dis[v][0]=1;
}
}
}
t=(int)(log(n)/log(2))+1;
for (int j=1;j<=t;j++)
for (int i=1;i<=40000;i++)
{
f[i][j]=f[f[i][j-1]][j-1];
dis[i][j]=min(dis[i][j-1],dis[f[i][j-1]][j-1]);
}
}
int lca(int x,int y)
{
if (k[x]>k[y]) swap(x,y);
for (int i=t;i>=0;i--)
if (k[f[y][i]]>=k[x]) y=f[y][i];
if (x==y) return x;
for (int i=t;i>=0;i--)
if (f[y][i]!=f[x][i])
{
x=f[x][i];
y=f[y][i];
}
return f[x][0];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>u>>v;
if(v==-1) root=u;
else a[u].push_back(v),a[v].push_back(u);
}
fun();
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>u>>v;
int Lca=lca(u,v);
if(Lca==u) cout<<1<<endl;
else if(Lca==v) cout<<2<<endl;
else cout<<0<<endl;
}
}