动态规划-换根DP简单例题

237 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
本文已参与「新人创作礼」活动,一 起开启掘金创作之路。

例题
代码源 224. 距离和

image.png
题目分析

从题意我们可以得出题目需要我们输出的答案是将每一个节点作为根节点时树的总深度之和
观察我们构造的树可以发现我们可以把树看成两个部分

image.png

如果此时我们要将2作为根节点时就相当于把2包括2的子树的深度全部加一将整个树中除了2的子树外的所有节点的深度全部加一所以我们就得到了一个递推公式的d[x]=d[fa]siz[x]+nsiz[x]d[x] = d[fa] - siz[x] + n - siz[x]

然后这题的结果就很好求出了
Code

int siz[N];
vector<int> v[N];
int d[N];
void dfs(int x,int fa) {
   siz[x] = 1;
   for(auto u : v[x]) {
      if(u == fa) continue;
      dfs(u,x);
      siz[x] += siz[u];
      d[x] += d[u] + siz[u];
   }
}
void dfs1(int x,int fa) {
   for(auto u : v[x]) {
      if(u == fa) continue;
      d[u] = d[x] - 2 * siz[u] + siz[1];
      dfs1(u,x);
   }
}
void solve()
{
   int n; cin >> n;
   for(int i = 2; i <= n; i++) {
      int x,y; cin >> x >> y;
      v[x].pb(y);
      v[y].pb(x);
   }
   dfs(1,0);
   dfs1(1,0);
   rep(i,n) cout << d[i] << endl;
}