main
黄海 2 years ago
parent fea7c9ae58
commit d65a1fdfdb

@ -1,35 +1,29 @@
#include <bits/stdc++.h>
#define endl '\n'
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 10;
vector<int> edge[N];
int f[N][25], g[N][25];
int val[N];
int n, k;
void dp(int u, int father) {
void dp(int u, int fa) {
for (int i = 0; i <= k; i++)
f[u][i] = val[u];
for (int i = 0; i < edge[u].size(); i++) {
int son = edge[u][i];
if (son == father)
continue;
if (son == fa) continue;
dp(son, u);
for (int j = 1; j <= k; j++) {
f[u][j] += f[son][j - 1];
}
for (int j = 1; j <= k; j++) f[u][j] += f[son][j - 1];
}
return;
}
void dp2(int u, int father) {
void dp2(int u, int fa) {
for (int i = 0; i < edge[u].size(); i++) {
int son = edge[u][i];
if (son == father)
if (son == fa)
continue;
g[son][0] = val[son];
g[son][1] = f[son][1] + val[u];
@ -41,7 +35,7 @@ void dp2(int u, int father) {
}
}
void solve() {
int main() {
cin >> n >> k;
for (int i = 0; i < n - 1; i++) {
int a, b;
@ -50,28 +44,11 @@ void solve() {
edge[b].push_back(a);
}
for (int i = 1; i <= n; i++)
cin >> val[i];
for (int i = 1; i <= n; i++) cin >> val[i];
dp(1, 0);
for (int i = 0; i <= k; i++) {
g[1][i] = f[1][i];
}
for (int i = 0; i <= k; i++) g[1][i] = f[1][i];
dp2(1, 0);
// for(int i = 1; i <= n; i ++ )
// {
// cout << f[i][k] << endl;
// }
// cout << endl;
for (int i = 1; i <= n; i++) {
cout << g[i][k] << endl;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
for (int i = 1; i <= n; i++) cout << g[i][k] << endl;
return 0;
}

@ -748,18 +748,17 @@ $$f[u][j]=val[u]+\sum_{v \in son[u]}f[v][j1] \ j \in [1,k]$$
![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202401151316634.png)
红色框是非常好理解的,直接写成$f[u][k]$即可。上面的部分,我们可以写成$g[fa(u)][k-1]$。
因为到$u$不超过$k$的距离,即距离它的父亲节点不超过$k1$的距离。
红色框是非常好理解的,以$v$为根的子树,在最远距离为$k$的限制下,写成$f[v][k]$。上面的部分,我们可以写成$g[u][k-1]$。因为到$v$不超过$k$的距离,即距离它的父亲节点不超过$k1$的距离。
但是这么写对吗?
答案是不对的,$g[fa(u)][k-1]$和$f[u][k]$是有重复部分的。我们需要减去这段重复的部分,那么关键问题是重复部分如何表示?
答案是不对的,$g[u][k-1]$和$f[v][k]$是有重复部分的。我们需要减去这段重复的部分,那么关键问题是重复部分如何表示?
重复部分肯定是出现在了红色框中,红色框中到$fa(u)$不超过距离$k1$,即距离$u$不超过$k-2$,同时重复部分又恰好是节点$u$的子节点,所以这部分可以表示为:$f[u][k-2]$。
重复部分肯定是出现在了红色框中,红色框中到$u$不超过距离$k1$,即距离$u$不超过$k-2$,同时重复部分又恰好是节点$v$的子节点,所以这部分可以表示为:$f[v][k-2]$。
所以最终的结果就是:
$$\large g[u][k]=f[u][k]+g[fa(u)][k1]f[u][k2]$$
$$\large g[v][k]=f[v][k]+g[u][k1]f[v][k2]$$
但是上述方程成立的条件是$k\geq 2$的。

Loading…
Cancel
Save