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; }
skr