注意建树过程。
大体思路:遍历第一个节点,保存路径path和节点深度。再遍历第二个节点,遇到和path相同的数即为ancestor。ancestor随时更新
易错点:建树
searchSecond函数中的 if (sum <= height && path[sum] == root->data) res = root->data;
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int SIZE = 80000;
int postOrder[SIZE];
int path[SIZE];
int res;
struct Node {
int data;
Node* left, * right;
Node() { left = right = NULL; }
};
void build(Node*& root, int left, int right) {
if (left > right) return;
if (root == NULL) {
root = new Node();
root->data = postOrder[left];
}
int mid = left + 1;
for (mid = left + 1; mid <= right; mid++) {
if (postOrder[mid] > postOrder[left]) break;
}
build(root->left, left + 1, mid - 1);
build(root->right, mid, right);
}
int height;
bool searchFirst(Node* root, int u, int sum) {
if (root == NULL) return false;
path[sum] = root->data;
if (root->data == u) {
height = sum;
return true;
}
if (root->data > u) searchFirst(root->left, u, sum + 1);
else searchFirst(root->right, u, sum + 1);
}
bool searchSecond(Node* root, int v, int sum) {
if (root == NULL) return false;
if (sum <= height && path[sum] == root->data) res = root->data;
if (root->data == v) {
return true;
}
if (root->data > v) searchSecond(root->left, v, sum + 1);
else searchSecond(root->right, v, sum + 1);
}
int main() {
int m, n;
scanf("%d %d", &m, &n);
for (int i = 0; i < n; i++) {
scanf("%d", &postOrder[i]);
}
Node* root = NULL;
build(root, 0, n - 1);
int u, v;
bool flag1, flag2;
for (int i = 0; i < m; i++) {
scanf("%d %d", &u, &v);
flag1 = searchFirst(root, u, 0);
flag2 = searchSecond(root, v, 0);
if (!flag1 || !flag2) {
if (flag1) printf("ERROR: %d is not found.\n", v);
else if (flag2) printf("ERROR: %d is not found.\n", u);
else printf("ERROR: %d and %d are not found.\n", u, v);
}
else {
if (res == u) printf("%d is an ancestor of %d.\n", u, v);
else if (res == v) printf("%d is an ancestor of %d.\n", v, u);
else printf("LCA of %d and %d is %d.\n", u, v, res);
}
}
return 0;
}