PAT 甲级 1151
采取先建立树的办法,然后该二叉树进行遍历,记录下每个结点的父结点和层次,由于key值在int范围内即可,故采用map容器来进行映射,并作为检验该key值是否存在的依据。
寻求LCA的过程,就是先将更深层的结点回溯到较低层次的结点,并判断是否为同一结点,若是则直接返回,否则就同时继续向更低层次回溯,直到找到LCA为止
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
struct node{
int data;
node *lchild,*rchild;
};
int inorder[10010],preorder[10010],n,m;
map<int,int> father,layer;
node* create(int inL,int inR,int preL,int preR)
{
if(preL>preR) return NULL;
node *root = new node;
root->data=preorder[preL];
root->lchild=root->rchild=NULL;
int k;
for(k=inL;k<=inR;k++)
if(inorder[k]==preorder[preL]) break;
int num2left=k-inL;
root->lchild=create(inL,k-1,preL+1,preL+num2left);
root->rchild=create(k+1,inR,preL+num2left+1,preR);
return root;
}
void traversal(node *root,int l)
{
layer[root->data]=l;
if(root->lchild!=NULL)
{
father[root->lchild->data]=root->data;
traversal(root->lchild,l+1);
}
if(root->rchild!=NULL)
{
father[root->rchild->data]=root->data;
traversal(root->rchild,l+1);
}
}
int findfather(int a,int b)
{
if(layer[a]>layer[b]) swap(a,b);
while(layer[a]<layer[b])
{
b=father[b];
}
if(b==a) return a;
while(b!=a)
{
a=father[a];
b=father[b];
}
return a;
}
int main()
{
scanf("%d%d",&m,&n);
for(int i=0;i<n;i++) scanf("%d",&inorder[i]);
for(int i=0;i<n;i++) scanf("%d",&preorder[i]);
node *root=create(0,n-1,0,n-1);
traversal(root,0);
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
if(layer.find(a)==layer.end()&&layer.find(b)==layer.end())
printf("ERROR: %d and %d are not found.\n",a,b);
else if(layer.find(a)==layer.end())
printf("ERROR: %d is not found.\n",a);
else if(layer.find(b)==layer.end())
printf("ERROR: %d is not found.\n",b);
else
{
int f=findfather(a,b);
if(f==a) printf("%d is an ancestor of %d.\n",a,b);
else if(f==b) printf("%d is an ancestor of %d.\n",b,a);
else printf("LCA of %d and %d is %d.\n",a,b,f);
}
}
return 0;
}

浙公网安备 33010602011771号