标签:getc oid pac long problem node char i++ print
[USACO10MAR]Great Cow Gathering G
换根dp模板题。
同时记录\(sz[u]\)代表\(u\)的子树内有多少奶牛,那转移时即为\(dp[u]=dp[v]+sz[v] \times val(u,v)\)。
注意开long long。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
const ll inf = 0x7f7f7f7f7f7f7f7f;
template <typename T> void read(T &x) {
T f = 1;
char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == ‘-‘) f = -1;
for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + ch - ‘0‘;
x *= f;
}
template <typename T> void cmin(T &x, T y) {if (y < x) x = y;}
struct node{
int pre, to;
ll val;
}edge[N << 1];
int head[N], tot;
int n;
int c[N];
ll dp[N], sz[N];
ll ans = inf;
void add(int u, int v, int l) {
edge[++tot] = node{head[u], v, l};
head[u] = tot;
}
void dfs1(int x, int fa) {
sz[x] = c[x];
for (int i = head[x]; i; i = edge[i].pre) {
int y = edge[i].to;
if (y == fa) continue;
dfs1(y, x);
sz[x] += sz[y];
dp[x] += dp[y] + sz[y] * edge[i].val;
}
}
void cut(int x, int y, int val) {
dp[x] -= dp[y] + sz[y] * val;
sz[x] -= sz[y];
}
void link(int x, int y, int val) {
dp[x] += dp[y] + sz[y] * val;
sz[x] += sz[y];
}
void change_root(int x, int y, int val) {
cut(x, y, val);
link(y, x, val);
}
void dfs2(int x, int fa) {
cmin(ans, dp[x]);
for (int i = head[x]; i; i = edge[i].pre) {
int y = edge[i].to;
if (y == fa) continue;
change_root(x, y, edge[i].val);
dfs2(y, x);
change_root(y, x, edge[i].val);
}
}
int main() {
read(n);
for (int i = 1; i <= n; i++) read(c[i]);
for (int i = 1, a, b, v; i < n; i++) {
read(a); read(b); read(v);
add(a, b, v);
add(b, a, v);
}
dfs1(1, 0);
dfs2(1, 0);
printf("%lld", ans);
return 0;
}
[USACO10MAR]Great Cow Gathering G(换根dp)
标签:getc oid pac long problem node char i++ print
原文地址:https://www.cnblogs.com/zcr-blog/p/13205101.html