题目
换根DP,手推一下即可。
代码如下:
cpp
#include <bits/stdc++.h>
#define int long long
#define MAXN 100010
using namespace std;
int N, A, B, L, C, minn = 0x3f3f3f3f3f3f3f3f, size[MAXN], dp[MAXN];
vector<pair<int, int>> tree[MAXN];
void dfs1(int u, int pa) {
size[u] = tree[u][0].first;
for (int i = 1; i < (int) tree[u].size(); i++) {
int v = tree[u][i].first, w = tree[u][i].second;
if (v == pa)
continue;
dfs1(v, u);
size[u] += size[v];
dp[u] += dp[v] + size[v] * w;
}
}
void dfs(int u, int pa) {
for (int i = 1; i < (int) tree[u].size(); i++) {
int v = tree[u][i].first, w = tree[u][i].second;
if (v == pa)
continue;
dp[v] = dp[u] - size[v] * w + (size[1] - size[v]) * w;
dfs(v, u);
}
}
signed main () {
scanf("%lld", &N);
for (int i = 1; i <= N; i++) {
scanf("%lld", &C);
tree[i].push_back({C, 0});
}
for (int i = 1; i < N; i ++) {
scanf("%lld%lld%lld", &A, &B, &L);
tree[A].push_back({B, L});
tree[B].push_back({A, L});
}
dfs1(1, 0);
dfs(1, 0);
for (int i = 1; i <= N; i++) {
minn = min(minn, dp[i]);
}
printf("%lld", minn);
}