【gomj】【LCA】 祖孙询问
题目
解题思路
lca板子题
lca是x那么x是y的祖先
如果是y那么y是x的祖先
不然什么都不是
代码
#include<iostream>
#include<cstdio>
using namespace std;
struct lzf{
int to,next;
}f[80010];
int n,m,x,y,t,g,tot;
int p[40010],a[40010],dep[40010],log[40010][32],head[40010];
void add(int x,int y)
{
f[++t].to=y;
f[t].next=head[x];
head[x]=t;
}
void dfs(int x,int fa)
{
dep[x]=dep[fa]+1,log[x][0]=fa,p[x]=1; //保存深度,父节点
for (int i=head[x];i;i=f[i].next)
if (!p[f[i].to]) dfs(f[i].to,x);
}
int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
int j=30;
while (dep[x]!=dep[y]) //先让两点在同一深度
{
if (dep[log[x][j]]>=dep[y])
x=log[x][j];
j--;
}
if (x==y) return x;
for (int j=30;j>=0;j--) //同时往上跳
if (log[x][j]!=log[y][j])
{
x=log[x][j];
y=log[y][j];
}
return log[x][0];
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
if (!a[x]) a[x]=++tot;
if (!a[y]&&y!=-1) a[y]=++tot;
if (y==-1) g=a[x];
else add(a[x],a[y]),add(a[y],a[x]);
}
t=0;
dfs(g,0);
for (int i=1;i<=30;i++)
for (int j=1;j<=tot;j++)
log[j][i]=log[log[j][i-1]][i-1];
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
int l=lca(a[x],a[y]);
if (l==a[x]) printf("1\n");
else if (l==a[y]) printf("2\n");
else printf("0\n");
}
return 0;
}