2021.8.10提高B组模拟2T2 祖孙询问(lca)(倍增)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.10提高B组模拟2T2 祖孙询问(lca)(倍增)相关的知识,希望对你有一定的参考价值。
祖孙询问
题目大意
输入样例
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(最近公共祖先)
如果 x,y 的 lca 为 x ,则 x 是 y 的祖先
lca 为 y,则 y 是 x 的祖先
否则为0
注:记得用倍增优化
AC代码
#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
int n,m,k,nn,tot,f[40005][20],deep[40005],head[40005];
struct node
int to,next;
a[80005];
void add(int x,int y)
a[++tot]=(node)y,head[x];
head[x]=tot;
void dfs(int x)//先弄出来树,每个节点的深度
for(int i=head[x];i;i=a[i].next)
deep[a[i].to]=deep[x]+1;
dfs(a[i].to);
int lca(int x,int y)//lca
int ans;
if(deep[x]<deep[y])ans=1,swap(x,y);
else
if(deep[x]>deep[y])ans=2;
else return 0;
for(int i=nn;i>0;i--)
if(deep[f[x][i]]>=deep[y])
x=f[x][i];
if(x!=y)return 0;
return ans;
int main()
scanf("%d",&n);
for(int i=1;i<=n;i++)
int x,y;
scanf("%d%d",&x,&y);
if(y==-1)k=x;
else f[x][1]=y,add(y,x);
deep[k]=1;
dfs(k);
nn=log2(n)+1;//预处理
for(int j=2;j<=nn;j++)
for(int i=1;i<=40000;i++)
f[i][j]=f[f[i][j-1]][j-1];
scanf("%d",&m);
for(int i=1;i<=m;i++)
int x,y;
scanf("%d%d",&x,&y);
printf("%d\\n",lca(x,y));
return 0;
谢谢
以上是关于2021.8.10提高B组模拟2T2 祖孙询问(lca)(倍增)的主要内容,如果未能解决你的问题,请参考以下文章