Codeforces 274B (168B) Zero Tree
問題
n頂点からなる無向木が与えられる。
頂点iには数字v[i]が書かれている。
この木に対して次の操作を好きなだけ行うことができる。
- 頂点1を含む部分木を選び、その頂点全ての数字を+1する
- 頂点1を含む部分木を選び、その頂点全ての数字を-1する
全ての頂点に書かれた数字を0にするのに必要な操作の回数の最小値を求めよ。
制約条件
n≦100000
v[i] | ≦10^9 |
方針
ノードi以下の部分木を0にするのに必要な+の回数をa[i],
必要な+の回数をb[i]とする。
すると、iの子孫の頂点を0にするときに、
最低でもiを、子孫に必要な+の数の最大値回だけ+を、
子孫に必要な+の数の最大値回だけ-をする必要がある。
その操作を行った後で、まだiのノードの数字に過不足があるなら、
その回数だけiに更に操作を行う必要がある。
これを再帰すればよい。
ソースコード
int n; ll v[100000]; vector<vi> e; pi rec(int c, int p){ pi res = mp(0, 0); rep(i, e[c].size()) if(e[c][i] != p){ pi tmp = rec(e[c][i], c); res.first = max(res.first, tmp.first); res.second = max(res.second, tmp.second); } ll a = v[c] + res.first - res.second; if(a < 0) res.first += -a; else res.second += a; return res; } int main(){ cin >> n; e.resize(n); rep(i, n - 1){ int a, b; cin >> a >> b; e[--a].pb(--b); e[b].pb(a); } rep(i, n) cin >> v[i]; pi res = rec(0, 0); cout << res.first + res.second << endl; return 0; }