版权声明:如需转载请联系[email protected] https://blog.csdn.net/qq_20633793/article/details/82534631
此题还是比较简单的,根据中序后续建立二叉树,然后DFS查找节点即可
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
#define MAXN 10005
#define INF 0x7fffffff
#define _for(i,lo,hi) for(int i=(lo);i<(hi);i++)
int preorder[MAXN],inorder[MAXN];
int N,M,K;
struct node{
int val,height;
node *lc,*rc,*p;
node(int v):val(v),height(0),lc(NULL),rc(NULL),p(NULL){}
};
node* root;
node* buildTree(int prelo,int prehi,int inlo,int inhi,int h){
if(prelo>=prehi)return NULL;
int tmp=preorder[prelo];
//cout<<tmp<<endl;
node* cur=new node(tmp);
cur->height=h;
int rank=inlo;
while(inorder[rank]!=tmp){
rank++;
}
cur->lc=buildTree(prelo+1,prelo+1+rank-inlo,inlo,rank,h+1);
cur->rc=buildTree(prehi-(inhi-rank-1),prehi,rank+1,inhi,h+1);
if(cur->lc)cur->lc->p=cur;
if(cur->rc)cur->rc->p=cur;
return cur;
}
set<int> sset;
node* findnode(int x,node* cur){
if(!cur)return NULL;
if(x==cur->val)return cur;
node* t1=findnode(x,cur->lc);
if(t1)return t1;
node* t2=findnode(x,cur->rc);
if(t2)return t2;
return NULL;
}
int main(){
//freopen("d:\\input.txt","r",stdin);
cin>>M>>N;
_for(i,0,N){cin>>inorder[i];sset.insert(inorder[i]);}
_for(i,0,N)cin>>preorder[i];
root=buildTree(0,N,0,N,0);
if(root->lc)root->lc->p=root;
if(root->rc)root->rc->p=root;
int c1,c2;
_for(i,0,M){
cin>>c1>>c2;
bool flag1=true,flag2=true;
if(sset.count(c1)==0)flag1=false;
if(sset.count(c2)==0)flag2=false;
if(flag1&&flag2){
node* t1=findnode(c1,root);
node* t2=findnode(c2,root);
while(t1->height>t2->height)t1=t1->p;
if(t1->val==t2->val){
printf("%d is an ancestor of %d.\n",c2,c1);
continue;
}
while(t1->height<t2->height)t2=t2->p;
if(t1->val==t2->val){
printf("%d is an ancestor of %d.\n",c1,c2);
continue;
}
while(t1->val!=t2->val){
t1=t1->p;t2=t2->p;
}
printf("LCA of %d and %d is %d.\n",c1,c2,t1->val);
}else if(flag1){
printf("ERROR: %d is not found.\n",c2);
}else if(flag2){
printf("ERROR: %d is not found.\n",c1);
}else{
printf("ERROR: %d and %d are not found.\n",c1,c2);
}
}
return 0;
}