自己真蠢,其实这题很简单,不需要建树,直接遍历preorder list就好了;
思路:
这是建树的笨方法:建树,先判断在不在树中,不在的话按要求输出;在的话按大小查找,找到的首个值介于需要查找的两个结点值之间的结点即lca;
自己真是蠢啊,用先根遍历序列去建树,然后去先根遍历找lca;
简单思路的就是之间在先根序列中找第一个值介于中间的点即lca;
代码:
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
vector<int> v;
unordered_map<int,pair<int,int>> mp;
void buildTree(int root,int begin,int end){
mp[v[root]];
if(end<begin) return;
int right;
for(right=begin;right<=end&&v[right]<v[root];right++);
if(v[begin]<v[root]){
mp[v[root]].first=v[begin];
buildTree(begin,begin+1,right-1);
}
if(right<=end){
mp[v[root]].second=v[right];
buildTree(right,right+1,end);
}
}
int main(){
int m,n;
scanf("%d%d",&m,&n);
v.resize(n);
for(int i=0;i<n;i++) scanf("%d",&v[i]);
buildTree(0,1,v.size()-1);
for(int i=0;i<m;i++){
int nd1,nd2;
scanf("%d%d",&nd1,&nd2);
bool find1=mp.find(nd1)!=mp.end(),find2=mp.find(nd2)!=mp.end();
if(!find1||!find2)
if(!find1&&!find2)
printf("ERROR: %d and %d are not found.
",nd1,nd2);
else
printf("ERROR: %d is not found.
",!find1?nd1:nd2);
else{
int anc=v[0];
while((anc-nd1)*(anc-nd2)>0) anc>nd1?anc=mp[anc].first:anc=mp[anc].second;
if((anc-nd1)*(anc-nd2)==0) printf("%d is an ancestor of %d.
",anc==nd1?nd1:nd2,anc==nd1?nd2:nd1);
else printf("LCA of %d and %d is %d.
",nd1,nd2,anc);
}
}
return 0;
}