// ZZQF5677
#include <bits/stdc++.h>
using namespace std;
int n, k, c[100005], head[100005], ecnt;
struct Node {
int v, nex;
} e[100005];
void add(int u, int v) {
ecnt++;
e[ecnt].v = v;
e[ecnt].nex = head[u];
head[u] = ecnt;
return ;
}
int zs[100001][21]; // 第 u 个点向下距离 j 的点权之和。
int dp[100001][21]; // 第 u 个点到它距离不超过 j,点权之和。
void dfs_information(int u, int fa, int d) {
for (int i = 0; i <= k; i++) {
zs[u][i] = c[u];
}
if (d <= k) {
for (int i = d; i <= k; i++) {
dp[1][i] += c[u];
}
}
for (int i = head[u]; i != 0; i = e[i].nex) {
int v = e[i].v;
if (v == fa) {
continue;
}
dfs_information(v, u, d + 1);
for (int j = 1; j <= k; j++) {
zs[u][j] += zs[v][j - 1];
}
}
return;
}
void dfs_dp(int u, int fa) {
for (int i = head[u]; i != 0; i = e[i].nex) {
int v = e[i].v;
if (v == fa) {
continue;
}
for (int j = 0; j <= k; j++) { // 从 0 开始,也要有只有自己的情况。
//dp[v][j] = dp[u][j - 1] - zs[v][j - 2] + zs[v][j - 1];
//dp[v][j] = dp[u][j - 1] - (j - 2 < 0 ? 0 : zs[v][j - 2]) + zs[v][j - 1];
//dp[v][j] = dp[u][j - 1] - (j - 2 < 0 ? 0 : zs[v][j - 2]) + zs[v][j];
dp[v][j] = (j - 1 < 0 ? 0 : dp[u][j - 1]) - (j - 2 < 0 ? 0 : zs[v][j - 2]) + zs[v][j];
// 容斥。
/*
int sum = 0;
for (int v_son = head[v]; v_son != 0; v_son = e[v_son].nex) {
int v_son_ = e[v_son].v;
if (v_son_ == v) {
continue;
}
sum += (zs[v_son_][j - 1] - (j - 2 < 0 ? 0 : zs[v_son_][j - 2]));
}
dp[v][j] += sum;
*/
}
dfs_dp(v, u);
}
return ;
}
int main() {
//freopen("1.in", "r", stdin);
cin >> n >> k;
for (int u, v, i = 1; i <= n - 1; i++) {
cin >> u >> v;
add(u, v);
add(v, u);
}
for (int i = 1; i <= n; i++) {
cin >> c[i];
}
dfs_information(1, 0, 0);
//cout << zs[5][1] << "\n";
//cout << dp[1][k] << "\n";
dfs_dp(1, 0);
//cout << dp[2][1] << "====\n";
for (int i = 1; i <= n; i++) {
cout << dp[i][k] << "\n";
}
return 0;
}
(式子推得有点乱)

thanks