Solution
普通的树形dp。
首先设为从点
向
的子树推流,所能达到的最大流量;
那么有:
其中为
的孩子,
为
和
之间的边的流量上限。
设为从
向整棵树推流,所能达到的最大流量,那么有:
作两遍dfs,分别求出和
的值,取
输出即可,复杂度
。
Code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct edge {
int v, cap;
};
vector<edge> G[200005];
ll dp[200005];
ll f(int v, int cap) {
if ((int) G[v].size() == 1) {
return cap;
} else {
return min<ll>(cap, dp[v]);
}
}
void dfs(int u, int fa) {
dp[u] = 0;
for (auto e : G[u]) {
if (e.v != fa) {
dfs(e.v, u);
dp[u] += f(e.v, e.cap);
}
}
}
void dfs(int u, int fa, int cap) {
if (fa > 0) {
dp[u] += min<ll>(cap, dp[fa] - f(u, cap));
}
for (auto e : G[u]) {
if (e.v != fa) {
dfs(e.v, u, e.cap);
}
}
}
int main() {
cin.sync_with_stdio(false), cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
G[i].clear();
}
for (int i = 0; i < n - 1; i++) {
int x, y, z;
cin >> x >> y >> z;
G[x].push_back({ y, z });
G[y].push_back({ x, z });
}
dfs(1, -1), dfs(1, -1, -1);
ll res = *max_element(dp + 1, dp + 1 + n);
cout << res << "\n";
}
} 
京公网安备 11010502036488号