
思路: 直接换根,不解释了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <iostream>
#include <map>
using namespace std;typedef long long ll;const int maxn = 4e5 + 7;int head[maxn],nex[maxn],to[maxn],tot;
ll a[maxn],d[maxn],f[maxn],sum[maxn],Sum;
ll ans[maxn];void add(int x,int y) {to[++tot] = y;nex[tot] = head[x];head[x] = tot;
}void dfs1(int x,int fa) {sum[x] = a[x];f[x] = a[x] * d[x];for(int i = head[x];i;i = nex[i]) {int v = to[i];if(v == fa) continue;d[v] = d[x] + 1;dfs1(v,x);sum[x] += sum[v];f[x] += f[v];}
}void dfs2(int x,int fa) {for(int i = head[x];i;i = nex[i]) {int v = to[i];if(v == fa) continue;ans[v] = f[v];ans[v] -= (d[v] - 1) * sum[v];ll num = ans[x] - (ans[v] + sum[v]);ans[v] += num + Sum - sum[v];dfs2(v,x);}
}int main() {int T;scanf("%d",&T);while(T--) {int n;scanf("%d",&n);tot = 0;for(int i = 1;i <= 2 * n;i++) {head[i] = 0;d[i] = 0;f[i] = 0;sum[i] = 0;ans[i] = 0;}Sum = 0;for(int i = 1;i <= n;i++) {scanf("%lld",&a[i]);Sum += a[i];}for(int i = 1;i < n;i++) {int x,y;scanf("%d%d",&x,&y);add(x,y);add(y,x);}d[1] = 1;dfs1(1,-1);ans[1] = f[1];dfs2(1,-1);for(int i = 1;i <= n;i++) {printf("%lld ",ans[i]);}printf("\n");}return 0;
}