pat 1151 LCA in a Binary Tree

pat 1151 LCA in a Binary Tree
起神解析很完善 暴力版

#include<bits/stdc++.h>
using namespace std;
const int maxsize = 10005;
struct Node {
    int val, father, h;
    Node(int v = -1, int h = 0, int father = -1): val(v), father(father), h(h) {};
} tree[maxsize];
int pre[maxsize], in[maxsize], m, n;
void createTree(int root, int l, int r, int father, int h) { // 构建树
    if(l > r) return;
    int i = l;
    while(in[i] != pre[root]) i++;
    tree[root] = Node(pre[root], h, father);
    createTree(root + 1, l, i - 1, root, h + 1);
    createTree(root + i - l + 1, i + 1, r, root, h + 1); // i这个位置左子树的数量 i - l, root + 左子树结点个数 + 1 为右根结点的位置
}
int main() {
    scanf("%d%d", &m, &n);
     for(int i = 0; i < n; i++) {
            scanf("%d", &in[i]);
        }
    for(int i = 0; i < n; i++) {
        scanf("%d", &pre[i]);
    }
    createTree(0, 0, n - 1 , -1, 0);
    while(m--) {
        int a, b, ia = -1, ib = -1;
        scanf("%d%d", &a, &b); // a, b记录待交换的值
        for(int i = 0; i < n; i++) {
            if(tree[i].val == a) // ia = i记录树几点的下标索引位置
                ia = i;
            if(tree[i].val == b) // ib 记录树结点的下标索引位置
                ib = i;
        }
        // 此处的判断
        if(ia == -1 && ib == -1) {
            printf("ERROR: %d and %d are not found.
", a, b);
        } else if(ia == -1) {
            printf("ERROR: %d is not found.
", a);
        } else if(ib == -1) {
            printf("ERROR: %d is not found.
", b);
        } else {
            bool ischange = false;
            if(tree[ia].h < tree[ib].h) {
                    swap(ia, ib);
                    ischange = true;
            }
            while(tree[ia].h > tree[ib].h) {
                ia = tree[ia].father;
            }
            if(tree[ia].val == tree[ib].val) {
                printf("%d is an ancestor of %d.
", tree[ia].val, ischange ? b : a);
            } else {
                while(tree[ia].val != tree[ib].val) {
                    ia = tree[ia].father;
                    ib = tree[ib].father;
                }
                printf("LCA of %d and %d is %d.
", a, b, tree[ia].val);
            }
        }

    }
	return 0;
}

LCA方法:

关键代码:

优质博客:https://blog.csdn.net/Q_M_X_D_D_/article/details/90047735

fa[i][j] //表示从编号为i的结点跳 2 的j 次方层所到达的结点
至于如何求出i结点可以跳到的结点, 运用递推式 fa[i][j] = fa[fa[i][j - 1]][j - 1],(也可以理解为 2的j次方 = 2的j -1 次方 + 2的 j - 1次方) 从根节点最上层执行,初始条件是 , fa[i][0] = father; 其中 j 能取到的最大值是 (1 << j) <= dep[i] // dep[i]表示树的高度
    
#include<bits/stdc++.h>
using namespace std;
const int maxsize = 10005;
int pre[maxsize], in[maxsize], dep[maxsize], fa[maxsize][20];
bool f = false; // 判断是否以及交换
void dfs(int root, int father, int l, int r) {
    if(l > r) return;
    dep[root] = dep[father] + 1;
    fa[root][0] = father;
    for(int i = 1; (1 << i) <= dep[root]; i++) {
        fa[root][i] = fa[fa[root][i - 1]][i - 1];
    }
    int i = l;
    while(in[i] != pre[root]) i++;
    dfs(root + 1, root, l, i - 1);
    dfs(root + (i - l) + 1, root, i + 1, r);
}
void LCA(int ia, int ib, int a, int b) {
    for(int i = 19; i >= 0; i--) {
        if(dep[ia] - (1 << i) >= dep[ib])
            ia = fa[ia][i];
    }
    if(ia == ib) printf("%d is an ancestor of %d.
", pre[ia], f ? b : a);
    else {
        for(int i = 19; i >= 0 ; i--) {
            if(fa[ia][i] != fa[ib][i]) {
                ia = fa[ia][i];
                ib = fa[ib][i];
            }
        }
        printf("LCA of %d and %d is %d.
", a, b, pre[fa[ia][0]]);
    }
}
int main() {
    int m, n;
    scanf("%d%d", &m, &n);
    for(int i = 0; i < n; i++) {
            scanf("%d", &in[i]);
    }
    for(int i = 0; i < n; i++) {
        scanf("%d", &pre[i]);
    }
    dfs(0, 0, 0, n - 1);
    while(m--) {
        int a, b, ia = -1, ib = -1;
        scanf("%d%d", &a, &b);
        for(int i = 0; i < n; i++) {
            if(a == pre[i]) ia = i;
            if(b == pre[i]) ib = i;
        }
        if(ia == -1 && ib == -1) {
            printf("ERROR: %d and %d are not found.
", a, b);
        } else if(ia == -1) {
            printf("ERROR: %d is not found.
", a);
        } else if(ib == -1) {
            printf("ERROR: %d is not found.
", b);
        } else {
            f = false;
            if(dep[ia] < dep[ib]) {
                swap(ia, ib);
                f = true;
            }
            LCA(ia, ib, a, b);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/csyxdh/p/12422096.html