原题目参见1151 LCA in a Binary Tree (30分)
此题紧邻着1143题,1143题的分析见我上一篇博客(1143 Lowest Common Ancestor (30分) 附测试点分析)。由于相比于1143题的二叉查找树,此题变为了普通的二叉树,所以对二叉树进行DFS遍历查询,每次查询的时间都为O(n),必定超时。题干保证每个节点间的数据各不相同,因此创建二叉树的时候设置一个map映射,将一个数据映射为节点指针,这样寻找祖先节点时候,只需要从该节点向父节点一直访问,将路径上的节点全部标记即可。第二个数据访问时,遇到的第一个被标记的节点即为要求的最近相邻祖先节点了。
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;
const int maxn = 10010;
struct Node {
int data, vis;
Node* lchild, * rchild, * father;
};
map<int, Node* >mp;
int pre[maxn], in[maxn];
Node* createNode(int data) {
Node* root = new Node;
root->data = data;
root->vis = 0;
root->lchild = root->rchild = root->father = NULL;
mp[data] = root;
return root;
}
Node* createTree(int prel, int prer, int inl, int inr) {
int rootd = pre[prel];
Node* root = createNode(rootd);
if (prel == prer) {
return root;
}
int rtinid = inl;
for (; rtinid <= inr; rtinid++) {
if (in[rtinid] == rootd) {
break;
}
}
int ln = rtinid - inl;
if (rtinid != inl) {
root->lchild = createTree(prel + 1, prel + ln, inl, rtinid - 1);
root->lchild->father = root;
}
if (rtinid != inr) {
root->rchild = createTree(prel + ln + 1, prer, rtinid + 1, inr);
root->rchild->father = root;
}
return root;
}
int tagFirst(Node* last) {
while (last != NULL) {
last->vis = 1;
last = last->father;
}
return 0;
}
int clearTag(Node* last) {
while (last != NULL) {
last->vis = 0;
last = last->father;
}
return 0;
}
int findLCA(Node* last) {
while (last != NULL) {
if (last->vis == 1) {
return last->data;
}
last = last->father;
}
return 0;
}
int lca(int a, int b) {
int flaga = mp.count(a);
int flagb = mp.count(b);
if (flaga && flagb) {
Node* lasta = mp[a];
Node* lastb = mp[b];
tagFirst(lasta);
int ans = findLCA(lastb);
clearTag(lasta);
if (ans == a) {
printf("%d is an ancestor of %d.\n", a, b);
}
else if (ans == b) {
printf("%d is an ancestor of %d.\n", b, a);
}
else {
printf("LCA of %d and %d is %d.\n", a, b, ans);
}
}
else if (!flaga && flagb) {
printf("ERROR: %d is not found.\n", a);
}
else if (flaga && !flagb) {
printf("ERROR: %d is not found.\n", b);
}
else if (!flaga && !flagb) {
printf("ERROR: %d and %d are not found.\n", a, b);
}
return 0;
}
int main() {
int n, m, a, b;
scanf("%d%d", &m, &n);
for (int i = 0; i < n; i++) {
scanf("%d", &in[i]);
}
for (int i = 0; i < n; i++) {
scanf("%d", &pre[i]);
}
createTree(0, n - 1, 0, n - 1);
for (int i = 0; i < m; i++) {
scanf("%d%d", &a, &b);
lca(a, b);
}
return 0;
}