传: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 ", fa[n]); } return 0; }