ZOJ - 3965 Binary Tree Restoring

传:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3965

题意:

  给定同一颗树的两个DFS的序列,输出这颗树。

思路:

  dfs,每次递归记录两个区间l1, r1, l2, r2 和pa.

 

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e5 + 9;
int a[maxn], b[maxn];
int fa[maxn];
int pta[maxn], ptb[maxn];
int sz[maxn];
int n;
void dfs(int al, int ar, int bl, int br, int pa) {
    if (al > ar || bl > br) return;
    if (al == ar || bl == br) {
        fa[a[al]] = pa;
        fa[b[bl]] = pa;
        sz[pa]++;
        return;
    }

    if (a[al] == b[bl]) {
        fa[a[al]] = pa;
        sz[pa]++;
        dfs(al + 1, ar, bl + 1, br, a[al]);
    } else {
        fa[a[al]] = pa;
        fa[b[bl]] = pa;

        sz[pa] += 2;

        int l1 = pta[b[bl]] - 1 - al - 1;
        dfs(al + 1, pta[b[bl]] - 1, ptb[a[al]] + 1, ptb[a[al]] + 1 + l1, a[al]);

        int l2 = ptb[a[al]] - 1 - bl - 1;
        dfs(pta[b[bl]] + 1, pta[b[bl]] + 1 + l2, bl + 1, ptb[a[al]] - 1, b[bl]);

        int mxa = al + l1 + l2 + 3;
        int mxb = bl + l1 + l2 + 3;
        int u = pa;
        while (sz[u] >= 2) u = fa[u];
        dfs(mxa + 1, ar, mxb + 1, br, u);
    }
}

int main() {
    int T;
    scanf("%d", &T);

    while (T--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]), pta[a[i]] = i, sz[i] = 0, fa[i] = 0;
        sz[0] = 0;
        for (int i = 1; i <= n; i++) scanf("%d", &b[i]), ptb[b[i]] = i;
        dfs(1, n, 1, n, 0);
        for (int i = 1; i < n; i++) printf("%d ", fa[i]);
        printf("%d\n", fa[n]);
    }
    return 0;
}
View Code

 

posted @ 2019-04-26 16:44  ckxkexing  阅读(197)  评论(0编辑  收藏  举报