题目大意:已知一个树的前序和中序序列,求两个结点的最近公共祖先
本着试一试的做法,直接建树,然后套倍增求LCA的算法,还好数据不是很大,没卡爆数组。
#include <iostream>
#include <unordered_set>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 10010;
int n,m,pre[N],iner[N],dis[N*100],fa[N*100][16];
struct node
{
int v;
node*left,*right;
node(int v) : v(v),left(NULL),right(NULL){}
}*tr;
unordered_set<int>se;
node *build(int preL,int preR,int inerL,int inerR)//前中建树
{
if(preL > preR) return NULL;
int k = inerL;
node* t = new node(pre[preL]);
se.insert(pre[preL]);
while(pre[preL] != iner[k]) k ++;//前序第一个结点就是根,在中序里面找根
t -> left = build(preL + 1,preL + k - inerL,inerL,k - 1);
t -> right = build(preL + k - inerL + 1,preR,k + 1,inerR);
return t;
}
void dfs(node *t,int d)
{
if(t->left != NULL)
{
int a = t ->left ->v;
if(dis[a] > d + 1)
{
dis[a] = d + 1;fa[a][0] = t->v;
for(int k = 1; k <= 15; k ++) fa[a][k] = fa[fa[a][k - 1]][k - 1];
dfs(t->left,d + 1);
}
}
if(t->right != NULL)
{
int a = t ->right ->v;
if(dis[a] > d + 1)
{
dis[a] = d + 1;fa[a][0] = t->v;
for(int k = 1; k <= 15; k ++) fa[a][k] = fa[fa[a][k - 1]][k - 1];
dfs(t->right,d + 1);
}
}
}
int lca(int a,int b)
{
if(dis[a] < dis[b]) swap(a,b);
for(int k = 15; k >= 0; k --)
if(dis[fa[a][k]] >= dis[b]) a = fa[a][k];
if(a == b) return a;
for(int k = 15; k >= 0; k --)
if(fa[a][k] != fa[b][k]) a = fa[a][k],b = fa[b][k];
return fa[a][0];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 0; i < m; i ++) scanf("%d",&iner[i]);
for(int i = 0; i < m; i ++) scanf("%d",&pre[i]);
tr = build(0,m - 1,0,m - 1);
memset(dis,0x3f,sizeof dis);
dis[0] = 0;dis[pre[0]] = 1;
dfs(tr,1);
for(int i = 0; i < n; i ++)
{
int a,b;
scanf("%d%d",&a,&b);
if(se.count(a) && !se.count(b)) printf("ERROR: %d is not found.\n",b);
else if(!se.count(a) && se.count(b)) printf("ERROR: %d is not found.\n",a);
else if(!se.count(a) && !se.count(b)) printf("ERROR: %d and %d are not found.\n",a,b);
else
{
int t = lca(a,b);
if(t == a) printf("%d is an ancestor of %d.\n",a,b);
else if(t == b) printf("%d is an ancestor of %d.\n",b,a);
else printf("LCA of %d and %d is %d.\n",a,b,t);
}
}
return 0;
}