60 pts求助(有关键代码的注释)
查看原帖
60 pts求助(有关键代码的注释)
482347
ZZQF5677楼主2024/3/3 18:07
// 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

2024/3/3 18:07
加载中...