pat1151 LCA in a Binary Tree

题意:输入一颗二叉树的中序,先序,q个询问,每次询问两个节点的lca。

思路:求dfs序,st表维护dfs序中的高度,map映射一下每个值对应的节点序号,rmq求lca。预处理O(nlogn)查询O(1)

代码

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

const int MAX_N = 10010;
int n, m, r, x, y;
int lc[MAX_N], rc[MAX_N], pre[MAX_N], in[MAX_N], fs[MAX_N];
int dfsorder[MAX_N<<2], height[MAX_N<<2], len = 0;
map mp;

int build(int il, int ir, int pl, int pr) {
    if (il >= ir) return -1;
    if (ir - il == 1) return pl;
    int rt = pl, p = -1;
    for (int i = il; i < ir; i++) {
        if (in[i] == pre[rt]) {
            p = i; break;
        }
    }
    lc[rt] = build(il, p, pl+1, pl+1+p-il);
    rc[rt] = build(p+1, ir, pl+1+p-il, pr);
    return rt;
}

void dfs(int rt, int h) {
    if (rt == -1) return ;
    fs[rt] = len; dfsorder[len] = rt; height[len] = h; len++;
    if (lc[rt] != -1) {dfs(lc[rt], h+1); dfsorder[len] = rt; height[len] = h; len++;}
    if (rc[rt] != -1) {dfs(rc[rt], h+1); dfsorder[len] = rt; height[len] = h; len++;}
}

int st[MAX_N<<1][30];
void init(int size) {
    for (int i = 0; i < size; i++) st[i][0] = i;
    for (int j = 1; 1< height[a]) return a;
    else return b;
}

int lca(int x, int y) {
    int l = fs[x];
    int r = fs[y];
    if (l > r) swap(l, r);
    return pre[dfsorder[rmq(l, r)]];
}

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    memset(lc, -1, sizeof(lc)); memset(rc, -1, sizeof(rc));
    memset(fs, -1, sizeof(fs));
    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]); mp[pre[i]] = i;}
    r = build(0, n, 0, n);
    dfs(r, 0);
    init(len);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &x, &y);
        if (mp.count(x) && mp.count(y)) {
            int id1 = mp[x], id2 = mp[y];
            int res = lca(id1, id2);
            if (res == x) printf("%d is an ancestor of %d.\n", x, y);
            else if (res == y) printf("%d is an ancestor of %d.\n", y, x);
            else printf("LCA of %d and %d is %d.\n", x, y, res);
        } else {
            if (mp.count(x)) printf("ERROR: %d is not found.\n", y);
            else if (mp.count(y)) printf("ERROR: %d is not found.\n", x);
            else {
                printf("ERROR: %d and %d are not found.\n", x, y);
            }
        }
    }
    return 0;
}

代码(暴力也能过)

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

const int MAX_N = 10010;
int n, m, x, y, r;
int in[MAX_N], pre[MAX_N], lc[MAX_N], rc[MAX_N];
map mp;

int build(int il, int ir, int pl, int pr) {
    if (il >= ir) return -1;
    if (ir - il == 1) return pl;
    int rt = pl, p = -1;
    for (int i = il; i < ir; i++) {
        if (in[i] == pre[rt]) {
            p = i; break;
        }
    }
    lc[rt] = build(il, p, pl+1, pl+1+p-il);
    rc[rt] = build(p+1, ir, pl+1+p-il, pr);
    return rt;
}

void lca(int x, int y) {
    int p = r, v = pre[r];
    int tx = mp[x], ty = mp[y];
    for(;;) {
        int tp = mp[v];
        if ((tx < tp && tp < ty) || (ty < tp && tp < tx)) {
            printf("LCA of %d and %d is %d.\n", x, y, v); return ;
        } else if (tx < tp && ty < tp) {
            p = lc[p]; v = pre[p];
        } else if (tx > tp && ty > tp) {
            p = rc[p]; v = pre[p];
        } else if (tx == tp) {
            printf("%d is an ancestor of %d.\n", x, y); return ;
        } else if (ty == tp) {
            printf("%d is an ancestor of %d.\n", y, x); return ;
        }
    }
}

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    scanf("%d %d", &m, &n);
    memset(lc, -1, sizeof(lc)); memset(rc, -1, sizeof(rc));
    for (int i = 0; i < n; i++) {
        scanf("%d", &in[i]);
        mp[in[i]] = i;
    }
    for (int i = 0; i < n; i++) scanf("%d", &pre[i]);
    r = build(0, n, 0, n);
    for (int i = 0; i < m; i++) {
        scanf("%d %d", &x, &y);
        if (!mp.count(x) && !mp.count(y)) {
            printf("ERROR: %d and %d are not found.\n", x, y);
        } else if (!mp.count(x)) {
            printf("ERROR: %d is not found.\n", x);
        } else if (!mp.count(y)) {
            printf("ERROR: %d is not found.\n", y);
        } else {
            lca(x, y);
        }
    }
    return 0;
}

 

你可能感兴趣的:(pat)