main
黄海 2 years ago
parent fea7c9ae58
commit d65a1fdfdb

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

@ -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) ![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202401151316634.png)
红色框是非常好理解的,直接写成$f[u][k]$即可。上面的部分,我们可以写成$g[fa(u)][k-1]$。 红色框是非常好理解的,以$v$为根的子树,在最远距离为$k$的限制下,写成$f[v][k]$。上面的部分,我们可以写成$g[u][k-1]$。因为到$v$不超过$k$的距离,即距离它的父亲节点不超过$k1$的距离。
因为到$u$不超过$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$的。 但是上述方程成立的条件是$k\geq 2$的。

Loading…
Cancel
Save