1151 LCA in a Binary Tree (30 分)

 题目大意:已知一个树的前序和中序序列,求两个结点的最近公共祖先

本着试一试的做法,直接建树,然后套倍增求LCA的算法,还好数据不是很大,没卡爆数组。

1151 LCA in a Binary Tree (30 分)

#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;

}

上一篇:elasticsearch练习--高级查询-range-范围查询


下一篇:火爆 Github,这几个标星 10W+的前端学习项目真牛