435 樹(shù)形DP 積蓄程度【動(dòng)態(tài)規(guī)劃】

```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點(diǎn)向下流出的最大流量
int up[N];??//up[u]記錄從u點(diǎn)向上流出的最大流量
int deg[N];??//deg[i]記錄點(diǎn)i的度數(shù)
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) { //從葉點(diǎn)開(kāi)始向上遞推u點(diǎn)的下流量
for (int i = h[u]; i; i = ne[i]) {
int v = to[i];
if (v == fa) continue;
int s = dfs_d(v, u);?//返回v點(diǎn)的下流量
d[u] += min(w[i], s); //累加u點(diǎn)的下流量
}
if (deg[u] == 1) return w[h[u]]; //若u是葉
return d[u];?????????//返回u點(diǎn)的下流量
}
void dfs_up(int u, int fa) { //從根點(diǎn)開(kāi)始向下遞推v點(diǎn)的上流量
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)是雍余邏輯