BST(二叉搜索树)与其先序遍历(preorder traversal sequence ),即先序遍历中每个点都可以看做是所在子树的根结点。而本题需要求出两个点的lca问题。根据BST的性质与先序遍历,可直接进行暴力,得到结果。
顺便在这里回顾一下以前的知识,BST的中序遍历就是BST中各结点从小到大排列好的结果。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int pre[N];
map<int, bool> pos;
int main()
{
int m, n;
scanf("%d%d", &m, &n);
for(int i=1; i<=n; i++){
scanf("%d", &pre[i]);
pos[pre[i]]=true;
}
int a, b;
while(m--){
scanf("%d%d", &a, &b);
if(!pos[a] && !pos[b]){
printf("ERROR: %d and %d are not found.\n", a, b);
} else if(!pos[a] || !pos[b]){
printf("ERROR: %d is not found.\n", !pos[a] ? a : b);
} else {
int res;
for(int i=1; i<=n; i++){
if((pre[i]<a && pre[i]>b) || (pre[i]>a && pre[i]<b) || (pre[i]==a) || (pre[i]==b)){
res=pre[i];
break;
}
}
if(res==a || res==b){
printf("%d is an ancestor of %d.\n", res==a ? a : b, res==a ? b : a);
} else {
printf("LCA of %d and %d is %d.\n", a, b, res);
}
}
}
return 0;
}
在这里贴一份,很久以前看别人的代码,虽然不如上面的好
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int pre[N];
map<int, int> pos;
void lca(int root, int a, int b){
if(pre[root]>a && pre[root]>b){
lca(root+1, a, b);
} else if((pre[root]<a && pre[root]>b) || (pre[root]>a && pre[root]<b)){
printf("LCA of %d and %d is %d.\n", a, b, pre[root]);
} else if(pos[pre[root]]<pos[a] && pos[pre[root]]<pos[b]){
int temp=root;
while(pre[temp]<=pre[root])
temp++;
lca(temp, a, b);
} else if(a==pre[root]){
printf("%d is an ancestor of %d.\n", a, b);
} else if(b==pre[root]){
printf("%d is an ancestor of %d.\n", b, a);
}
}
int main()
{
int m, n;
scanf("%d%d", &m, &n);
for(int i=1; i<=n; i++){
scanf("%d", &pre[i]);
pos[pre[i]]=i;
}
int a, b;
for(int i=1; i<=m; i++){
scanf("%d%d", &a, &b);
if(pos[a] && !pos[b]){
printf("ERROR: %d is not found.\n", b);
} else if(!pos[a] && pos[b]){
printf("ERROR: %d is not found.\n", a);
} else if(!pos[a] && !pos[b]){
printf("ERROR: %d and %d are not found.\n", a, b);
} else {
lca(1, a, b);
}
}
return 0;
}