0
点赞
收藏
分享

微信扫一扫

A1151 LCA in a Binary Tree (30 分| 树的遍历| LCA算法,附详细注释,逻辑分析)


写在前面

  • 思路分析
  • 无须构建树,递归每1层得到树的根结点,通过lca算法确定两个结点公共祖先
  • ​lca​​ 自定义函数
  • 已知某树根结点
  • a和b在根结点左边,则a和b最近公共祖先在当前子树根结点的左子树寻找
  • a和b在当前子树根结点两边,当前子树根结点就是a和b的最近公共祖先
  • a和b在当前子树根结点右边,则a和b的最近公共祖先在当前子树右子树寻找
  • 新知识盲点,学习ing
  • 第1遍略懂

测试用例

input:
6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99

output:
LCA of 2 and 6 is 3.
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.

ac代码

  • 参考链接

#include <iostream>
#include <vector>
#include <map>
using namespace std;

map<int, int> pos;
vector<int> in, pre;
void lca(int inl, int inr, int preRoot, int a, int b)
{
if(inl > inr) return;
int inRoot = pos[pre[preRoot]], aIn = pos[a], bIn=pos[b];
if(aIn < inRoot && bIn < inRoot)
lca(inl, inRoot-1, preRoot+1, a, b);
else if((aIn < inRoot && bIn>inRoot) || (aIn>inRoot && bIn<inRoot))
printf("LCA of %d and %d is %d.\n", a, b, in[inRoot]);
else if(aIn > inRoot && bIn > inRoot)
lca(inRoot+1, inr, preRoot+1+(inRoot-inl), a, b);
else if(aIn == inRoot)
printf("%d is an ancestor of %d.\n", a, b);
else if(bIn == inRoot)
printf("%d is an ancestor of %d.\n", b, a);
}

int main()
{
int m, n, a, b;
scanf("%d %d", &m,&n);
in.resize(n+1), pre.resize(n+1);
for(int i=1; i<=n; i++)
{
scanf("%d", &in[i]);
pos[in[i]] = i;
}
for(int i=1; i<=n; i++) scanf("%d", &pre[i]);
for(int i=0; i<m; i++)
{
scanf("%d %d", &a, &b);
if(pos[a] == 0 && pos[b]==0)
printf("ERROR: %d and %d are not found.\n", a, b);
else if(pos[a]==0 || pos[b]==0)
printf("ERROR: %d is not found.\n", pos[a] == 0 ? a : b);
else
lca(1, n, 1, a, b);
}

return 0;
}

知识点小结

  • ​LCA(Least Common Ancestors)​
  • 即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。
  • 主要用途
  • 用来处理当两个点仅有唯1条确定的最短路径时的路径。


举报

相关推荐

0 条评论