有一颗有个结点树,结点被编号为~,记根结点深度为,如果第个结点的深度是,则它贡献的价值是 ,这棵树的价值是所有结点的价值和 求当根结点为~时,树的价值分别为多少
输入描述
第一行输入一个整数,代表有组测试数据 对于每一组测试数据,第一行有个整数,第二行有个整数,接下来行每行有两个整数表示和之间有一条边
输出描述
对于每组测试数据,在一行中输出个整数,第个整数代表以结点为根结点时树的价值
数据范围
输出时每行末尾的多余空格,不影响答案正确性
样例输入
2
6
5 2 8 1 7 8
4 5
5 6
2 5
1 3
4 3
5
1 1 1 1 1
1 2
2 3
3 4
4 5
样例输出
102 100 81 76 73 88
15 12 11 12 15
二次扫描与换根法。
初始设号节点。为以节点为根的子树中的和;为以节点为根的子树的价值;。
设为以节点为根是整棵树的价值,则对于节点的子节点,。
树形dp即可。时间复杂度为。
#include<bits/stdc++.h>
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector<int>
#define pii pair<int,int>
#define mii unordered_map<int,int>
#define msi unordered_map<string,int>
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<<x<<endl
using namespace std;
inline int qr() {
int f = 0, fu = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')fu = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
f = (f << 3) + (f << 1) + c - 48;
c = getchar();
}
return f * fu;
}
const int N = 2e5 + 10;
int head[N], ver[N << 1], Next[N << 1], tot;
int n, T;
ll sumw[N], sumv[N], ans[N], W;
inline void add(int x, int y) {
ver[++tot] = y;
Next[tot] = head[x];
head[x] = tot;
}
inline void init() {
repi(i, 1, n)head[i] = sumv[i] = 0;
tot = W = 0;
}
void dfs(int x, int f) {
reps(x) {
int y = ver[i];
if (y == f)continue;
dfs(y, x);
sumw[x] += sumw[y];
sumv[x] += sumv[y];
}
sumv[x] += sumw[x];
}
void dp(int x, int f) {
reps(x) {
int y = ver[i];
if (y == f)continue;
ans[y] = ans[x] - sumw[y] + W - sumw[y];
dp(y, x);
}
}
int main() {
T = qr();
while (T--) {
n = qr();
init();
repi(i, 1, n)sumw[i] = qr(), W += sumw[i];
repi(i, 1, n - 1) {
int x = qr(), y = qr();
add(x, y), add(y, x);
}
dfs(1, 0);
ans[1] = sumv[1];
dp(1, 0);
repi(i, 1, n)printf("%lld%c", ans[i], ce(i, n));
}
return 0;
}