欢迎光临散文网 会员登陆 & 注册

435 树形DP 积蓄程度【动态规划】

2023-04-26 15:06 作者:零-雪鸦  | 我要投稿

```C++

#include <iostream>

#include <cstring>

#include <algorithm>

using namespace std;


const int N = 200010, INF = 0x3f3f3f3f;

int h[N], to[N * 2], w[N * 2], ne[N * 2], tot; //邻接表

int d[N];   //d[u]记录从u点向下流出的最大流量

int up[N];  //up[u]记录从u点向上流出的最大流量

int deg[N];  //deg[i]记录点i的度数


void add(int a, int b, int c) {

to[++tot] = b, w[tot] = c, ne[tot] = h[a], h[a] = tot;

}

int dfs_d(int u, int fa) { //从叶点开始向上递推u点的下流量

for (int i = h[u]; i; i = ne[i]) {

int v = to[i];

if (v == fa) continue;

int s = dfs_d(v, u); //返回v点的下流量

d[u] += min(w[i], s); //累加u点的下流量

}

if (deg[u] == 1) return w[h[u]]; //若u是叶

return d[u];         //返回u点的下流量

}

void dfs_up(int u, int fa) { //从根点开始向下递推v点的上流量

for (int i = h[u]; i; i = ne[i]) {

int v = to[i];

if (v == fa) continue;

if (deg[u] == 1) up[v] = w[i];

// else if (deg[v] == 1) up[v] = min(w[i], d[u] - w[i] );

else up[v] = min( d[u] - min(d[v], w[i]) + up[u], w[i]);

dfs_up(v, u);

}

}

int main() {

int t, n;

scanf("%d", &t);

while (t--) {

scanf("%d", &n);

tot = 0;

memset(h, 0, sizeof h);

memset(d, 0, sizeof d);

memset(up, 0, sizeof up);

memset(deg, 0, sizeof deg);

for (int i = 1; i < n; i++) {

int a, b, c;

scanf("%d%d%d", &a, &b, &c);

add(a, b, c), add(b, a, c);

deg[a]++, deg[b]++;

}


dfs_d(1, -1); //向上递推下流量

up[1] = 0;  //根的上流量为0

dfs_up(1, -1); //向下递推上流量

int ans = 0;

for (int i = 1; i <= n; i++) ans = max(ans, up[i] + d[i]);

printf("%d\n", ans);

}

return 0;

}

```


注释部分是代码 else if (deg[v] == 1)是雍余逻辑

435 树形DP 积蓄程度【动态规划】的评论 (共 条)

分享到微博请遵守国家法律