1151 LCA in a Binary Tree (30 分)
题目要求
给定中序和前序以及两个结点,判断他们的最近公共祖先
解题思想
如果两个结点位于根结点的两侧,则此根结点即为所求
如果两个结点位于根结点的左侧,则向左子树查找
如果两个结点位于根结点的右侧,则向右子树查找
如果其中一个结点为当前子树的根结点,则该结点为另一结点的最近公共祖先
AC代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
int m, n;
vector<int> in, pre;
map<int, int> in_pos;
void LCA(int inl, int inr, int pre_root_pos, int a, int b){
if (inl > inr) return;
int in_root_pos = in_pos[pre[pre_root_pos]];
int a_in = in_pos[a], b_in = in_pos[b];
if (a_in < in_root_pos && b_in < in_root_pos)
LCA(inl, in_root_pos-1, pre_root_pos+1, a, b);
else if ((a_in < in_root_pos && b_in > in_root_pos)
|| (b_in < in_root_pos && a_in > in_root_pos))
printf("LCA of %d and %d is %d.\n", a, b, in[in_root_pos]);
else if (a_in > in_root_pos && b_in > in_root_pos)
LCA(in_root_pos+1, inr, pre_root_pos+in_root_pos-inl+1, a, b);
else if (a_in == in_root_pos) printf("%d is an ancestor of %d.\n", a, b);
else if (b_in == in_root_pos) printf("%d is an ancestor of %d.\n", b, a);
}
int main(){
scanf("%d%d", &m, &n);
in.resize(n+1);
pre.resize(n+1);
for (int i = 1; i <= n; i++){
scanf("%d", &in[i]);
in_pos[in[i]] = i;
}
for (int i = 1; i <= n; i++)
scanf("%d", &pre[i]);
int a, b;
while (m--){
scanf("%d%d", &a, &b);
if (!in_pos[a] && !in_pos[b])
printf("ERROR: %d and %d are not found.\n", a, b);
else if (!in_pos[a] || !in_pos[b])
printf("ERROR: %d is not found.\n", in_pos[a] ? b : a);
else LCA(1, n, 1, a, b);
}
return 0;
}