典型树上dp,直接暴力算会超时,小心呀
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #include<vector> #define maxn 100010 using namespace std; typedef long long ll; struct Node { int p; ll len; Node(int a, ll b) :p(a), len(b) {} }; vector<Node>G[maxn]; void insert(int be, int en,ll len) { G[be].push_back(Node(en, len)); } int n, m; ll sum = 0; ll ran[maxn]; ll ans[maxn]; ll list[maxn]; int dfs1(int x, int fa) { ll k = 0; for (int i = 0; i < G[x].size(); i++) { int p = G[x][i].p; ll ln = G[x][i].len; if (p == fa) continue; dfs1(p, x); k = ran[p]; ans[x] += (ans[p] + ran[p] * ln); ran[x] += ran[p]; } return 0; } int dfs(int x, int fa) { for (int i = 0; i < G[x].size(); i++) { int p = G[x][i].p; ll ln = G[x][i].len; if (p == fa) continue; ans[p] += ans[x] - (ans[p] + ran[p] * ln) + (sum - ran[p])*ln; dfs(p, x); } return 0; } int main() { scanf("%d", &n); m = n - 1; for (int i = 1; i <= n; i++) { scanf("%lld", &list[i]); sum += list[i]; ran[i] = list[i]; } int be, en; ll len; for (int i = 0; i < m; i++) { scanf("%d%d%lld", &be, &en, &len); insert(be, en, len); insert(en, be, len); } dfs1(1, -1); dfs(1, -1); ll cns = 10000000000000000; for (int i = 1; i <= n; i++) { cns = min(cns, ans[i]); } printf("%lld ", cns); return 0; }