朴素做法:
给定了先序 先序排个序得到中序 然后建树 然后LCA就行了
LCA可以有两种:一种是当普通二叉树来跑,另一种就是在BST里跑
普通二叉树LCA:
Tree lca(Tree tree,int a,int b)
{
if(!tree||tree->data==a||tree->data==b)
return tree;
Tree l=lca(tree->left,a,b);
Tree r=lca(tree->right,a,b);
if(l==NULL) return r;
if(r==NULL) return l;
return tree;
}
BST里跑LCA
Tree lca(Tree tree,int a,int b)
{
if(tree->data>max(a,b))
return lca(tree->left,a,b);
else if(tree->data<min(a,b))
return lca(tree->right,a,b);
else return tree;
}
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e4+5;
struct node{
int data;
node *left;
node *right;
};
typedef node* Tree;
int pre[maxn],in[maxn];
Tree build(int len,int pre[],int in[])
{
if(len==0)
return NULL;
Tree temp=new node;
temp->data=pre[0];
int i;
for(i=0;i<len;i++)
if(in[i]==pre[0])
break;
temp->left=build(i,pre+1,in);
temp->right=build(len-i-1,pre+i+1,in+i+1);
return temp;
}
Tree lca(Tree tree,int a,int b)
{
if(tree->data>max(a,b))
return lca(tree->left,a,b);
else if(tree->data<min(a,b))
return lca(tree->right,a,b);
else return tree;
}
map<int,int> mp;
int main()
{
int n,q;
scanf("%d%d",&q,&n);
for(int i=0;i<n;i++)
{
scanf("%d",&pre[i]);
mp[pre[i]]=1;
in[i]=pre[i];
}
sort(in,in+n);
Tree tree=build(n,pre,in);
for(int i=0;i<q;i++)
{
int u,v;
scanf("%d%d",&u,&v);
if(mp[u]&&mp[v])
{
int temp=lca(tree,u,v)->data;
if(u==temp)
printf("%d is an ancestor of %d.\n",u,v);
else if(v==temp)
printf("%d is an ancestor of %d.\n",v,u);
else
printf("LCA of %d and %d is %d.\n",u,v,temp);
}
else if(mp[u])
printf("ERROR: %d is not found.\n",v);
else if(mp[v])
printf("ERROR: %d is not found.\n",u);
else printf("ERROR: %d and %d are not found.\n",u,v);
}
return 0;
}
巧妙做法:
由于是BST, 给定了先序序列,我们只需要从头开始遍历先序序列,记当前节点的值为a,如果u,v分别在a的左右子树,则a是他俩的LCA,否则继续往后找。
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e4+5;
struct node{
int data;
node *left;
node *right;
};
typedef node* Tree;
int pre[maxn];
map<int,int> mp;
int main()
{
int m,n,u,v,a;
scanf("%d%d",&m,&n);
for (int i = 0; i < n; i++)
{
scanf("%d", &pre[i]);
mp[pre[i]] = 1;
}
for (int i = 0; i < m; i++)
{
scanf("%d %d", &u, &v);
for(int j = 0; j < n; j++)
{
a = pre[j];
if ((a >= u && a <= v) || (a >= v && a <= u)) break;
}
if(mp[u]&&mp[v])
{
int temp=a;
if(u==temp)
printf("%d is an ancestor of %d.\n",u,v);
else if(v==temp)
printf("%d is an ancestor of %d.\n",v,u);
else
printf("LCA of %d and %d is %d.\n",u,v,temp);
}
else if(mp[u])
printf("ERROR: %d is not found.\n",v);
else if(mp[v])
printf("ERROR: %d is not found.\n",u);
else printf("ERROR: %d and %d are not found.\n",u,v);
}
return 0;
}