#pragma comment (linker, "/STACK:1073741824") #define _USE_MATH_DEFINES #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define SZ(x) (int((x).size())) #define FOR(i, a, b) for(int (i) = (a); (i) <= (b); ++(i)) #define ROF(i, a, b) for(int (i) = (a); (i) >= (b); --(i)) #define REP(i, n) for (int (i) = 0; (i) < (n); ++(i)) #define REPD(i, n) for (int (i) = (n); (i)--; ) #define FE(i, a) for (int (i) = 0; (i) < (int((a).size())); ++(i)) #define MEM(a, val) memset((a), val, sizeof(a)) #define INF 1000000000 #define LLINF 1000000000000000000LL #define PB push_back #define PPB pop_back #define ALL(c) (c).begin(), (c).end() #define SQR(a) ((a)*(a)) #define MP(a,b) make_pair((a), (b)) #define XX first #define YY second #define GET_RUNTIME_ERROR *(int*)(NULL) = 1 typedef vector vint; typedef vector vLL; typedef double dbl; typedef long double ldbl; typedef vector > vpii; typedef long long LL; typedef pair pii; const int nmax = 100100; vector g[nmax]; int a[nmax]; int mx[nmax]; int mx_except_root[nmax]; int mx_except_2layers[nmax]; int ans[nmax]; template pair make_max_pair(const T& a, const T& b) { return MP(max(a, b), min(a, b)); } // Find the maximums in the subtree, subtree without root and subtree without // root and root's neighbours. void dfs_mx(int v, int p) { mx_except_root[v] = 0; mx_except_2layers[v] = 0; for (int to : g[v]) { if (to == p) { continue; } dfs_mx(to, v); mx_except_root[v] = max(mx_except_root[v], mx[to]); mx_except_2layers[v] = max(mx_except_2layers[v], mx_except_root[to]); } mx[v] = max(a[v], mx_except_root[v]); } // Calculate the answer as described in the editorial. void dfs_ans(int v, int p, int max_top_except_par, int par_value) { pair subtrees_max; for (int to : g[v]) { if (to == p) { continue; } subtrees_max = max(subtrees_max, make_max_pair(subtrees_max.first, mx[to])); } ans[v] = max(mx_except_2layers[v], max_top_except_par); int max_top = max(max_top_except_par, par_value); for (int to : g[v]) { if (to == p) { continue; } // If the maximum belongs to the subtree we are going to go, let's pick the // second maximum. int val = subtrees_max.first == mx[to] ? subtrees_max.second : subtrees_max.first; dfs_ans(to, v, max(val, max_top), a[v]); } } // Solves the test. void solve() { int n; cin >> n; REP(i, n) cin >> a[i]; REP(i, n) { g[i].clear(); } REP(i, n - 1) { int v, u; cin >> v >> u; --v, --u; assert(0 <= v && v < n); assert(0 <= u && u < n); g[v].PB(u); g[u].PB(v); } dfs_mx(0, -1); dfs_ans(0, -1, 0, 0); // Find the reverse function F:value->index vector> reverse; reverse.reserve(n); REP(i, n) { reverse.PB(MP(a[i], i)); } sort(ALL(reverse)); REP(i, n) { assert(ans[i] != 0); int index = lower_bound(ALL(reverse), MP(ans[i], -1))->second + 1; printf("%d%c", index, i + 1 == n ? '\n' : ' '); } } int main() { ios_base::sync_with_stdio(false); int t; cin >> t; while(t--) { solve(); } return 0; }