原题链接:蓝桥杯2018年第九届真题-版本分支
解题思路:
常规的求祖先方法往往一次向上移动1,采用倍增的方法一次向上移动2^k,nlogn处理出倍增数组,logn查询。
注意事项:
提一个题解区没说的,不要用cin读,会超时。
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define maxx 130000
#define int long long
int n,q,a,b;
int fa[maxx];
int faaa[maxx][22];
vector<int> G[maxx];
int dep[maxx];
void starting()
{
for(int i=1;i<=n;++i)
faaa[i][0]=fa[i];
for(int j=1;j<=20;++j) //循环位置
for(int i=1;i<=n;++i)
faaa[i][j]=faaa[faaa[i][j-1]][j-1];
}
void dfs(int i)
{
for(int j=0;j<G[i].size();++j)
{dep[G[i][j]]=dep[i]+1;
dfs(G[i][j]);}
}
int cal(int x,int y)
{
if(dep[x]>dep[y]) return 0;
int cha=dep[y]-dep[x];
for(int i=0;i<20;++i)
{
if(cha%2==1) y=faaa[y][i];
cha/=2;
}
if(y==x) return 1;
else return 0;
}
signed main()
{
scanf("%d %d",&n,&q);
for(int i=1;i<n;++i)
{scanf("%d %d",&a,&b);
fa[b]=a;
G[a].push_back(b);
}
for(int i=1;i<=n;++i)
if(fa[i]==0) dfs(i);
starting();
for(int i=1;i<=q;++i)
{
scanf("%d %d",&a,&b);
if(cal(a,b)) cout<<"YES\n";
else cout<<"NO\n";
}
}0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复