diff --git a/TangDou/Topic/HuanGenDp/P3047.cpp b/TangDou/Topic/HuanGenDp/P3047.cpp index 450112a..bbcce25 100644 --- a/TangDou/Topic/HuanGenDp/P3047.cpp +++ b/TangDou/Topic/HuanGenDp/P3047.cpp @@ -1,35 +1,29 @@ #include -#define endl '\n' -#define INF 0x3f3f3f3f using namespace std; -typedef long long ll; -typedef pair pii; + const int N = 1e5 + 10; vector 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; } diff --git a/TangDou/Topic/【换根】dfs专题.md b/TangDou/Topic/【换根】dfs专题.md index 92bd07d..2799326 100644 --- a/TangDou/Topic/【换根】dfs专题.md +++ b/TangDou/Topic/【换根】dfs专题.md @@ -748,18 +748,17 @@ $$f[u][j]=val[u]+\sum_{v \in son[u]}f[v][j−1] \ 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$的距离,即距离它的父亲节点不超过$k−1$的距离。 +红色框是非常好理解的,以$v$为根的子树,在最远距离为$k$的限制下,写成$f[v][k]$。上面的部分,我们可以写成$g[u][k-1]$。因为到$v$不超过$k$的距离,即距离它的父亲节点不超过$k−1$的距离。 但是这么写对吗? -答案是不对的,$g[fa(u)][k-1]$和$f[u][k]$是有重复部分的。我们需要减去这段重复的部分,那么关键问题是重复部分如何表示? +答案是不对的,$g[u][k-1]$和$f[v][k]$是有重复部分的。我们需要减去这段重复的部分,那么关键问题是重复部分如何表示? -重复部分肯定是出现在了红色框中,红色框中到$fa(u)$不超过距离$k−1$,即距离$u$不超过$k-2$,同时重复部分又恰好是节点$u$的子节点,所以这部分可以表示为:$f[u][k-2]$。 +重复部分肯定是出现在了红色框中,红色框中到$u$不超过距离$k−1$,即距离$u$不超过$k-2$,同时重复部分又恰好是节点$v$的子节点,所以这部分可以表示为:$f[v][k-2]$。 所以最终的结果就是: -$$\large g[u][k]=f[u][k]+g[fa(u)][k−1]−f[u][k−2]$$ +$$\large g[v][k]=f[v][k]+g[u][k−1]−f[v][k−2]$$ 但是上述方程成立的条件是$k\geq 2$的。