Problem:
F: ボタンの木

問題文

$N$ 頂点 $N-1$ 辺からなる木があり、$i$ 番目の辺は $u_i$ 番目の頂点と $v_i$ 番目の頂点を接続しています。

各頂点にはボタンが咲いており、$i$ 番目の頂点に咲いているボタンをボタン $i$ と呼ぶことにします。

はじめ、ボタン $i$ の美しさは $a_i$ です。

ボタン $i$ を押すたびに、ボタン $i$ の美しさを隣接するボタンに $1$ ずつ分け与えます。

すなわち、$i$ 番目の頂点に $c_1, ..., c_k$ 番目の頂点が隣接している場合、ボタン $i$ の美しさが $k$ 減少し、ボタン $c_1, ..., c_k$ の美しさがそれぞれ $1$ ずつ増加します。

このとき、負の美しさのボタンを押しても良いし、ボタンを押した結果あるボタンの美しさが負になっても良いです。

あなたの目的はボタン $1, 2, ..., N$ の美しさをそれぞれ $b_1, ..., b_N$ にすることです。

最小で合計何回ボタンを押せば目的を達成できるでしょうか。

制約

入力はすべて整数である

$1 \leq N \leq 10^5$

$1 \leq u_i, v_i \leq N$

$-1000 \leq a_i, b_i \leq 1000$

$\sum_i a_i = \sum_i b_i$

与えられるグラフは木である

与えられる入力において目的は必ず達成できる

入力

入力は以下の形式で標準入力から与えられる。

$N$
$u_1$ $v_1$
$\vdots$
$u_{N-1}$ $v_{N-1}$
$a_1$ $a_2$ $...$ $a_N$
$b_1$ $b_2$ $...$ $b_N$

出力

目的を達成するためにボタンを押す合計回数の最小値を出力せよ。

入力例1

4
1 2
1 3
3 4
0 3 2 0
-3 4 5 -1

出力例1

4

次のように合計 $4$ 回ボタンを押すことで目的を達成でき、このときが最小です。

ボタン $1$ を $2$ 回押します。ボタン $1, 2, 3, 4$ の美しさがそれぞれ $-4, 5, 4, 0$ に変化します。

ボタン $2$ を $1$ 回押します。美しさがそれぞれ $-3, 4, 4, 0$ に変化します。

ボタン $4$ を $1$ 回押します。美しさがそれぞれ $-3, 4, 5, -1$ に変化します。

入力例2

5
1 2
1 3
3 4
3 5
-9 5 7 1 8
-7 4 5 1 9

出力例2

3

Solution in C++11 (judge verdict: Accepted)

#include <iostream>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <deque>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <map>
#include <stack>
#include <queue>
#include <functional>
#include <climits>
#include <bitset>
#include <random>
#include <tuple>
#include <initializer_list>
#include <fstream>

struct SubTree {
	long long int min_step, back_for_minstep, need_to_push;
	long long int push_back_multiplier, sum_initial, sum_target;
};
int main() {
	int n; std::cin >> n;
	std::vector<std::vector<int>> nodes(n);
	for (auto i = 1; i < n; ++i) {
		int u, v; std::cin >> u >> v;
		nodes[--u].push_back(--v);
		nodes[v].push_back(u);
	}
	std::vector<int> initial_size(n), target_size(n);
	for (auto& a : initial_size) std::cin >> a;
	for (auto& b : target_size) std::cin >> b;
	std::vector<int> depth(n, -1), parent(n, -1), child_count(n, 0); depth[0] = 0;
	std::stack<int> stack; stack.push(0);
	while (!stack.empty()) {
		const auto top = stack.top(); stack.pop();
		for (const auto next : nodes[top]) if (depth[next] == -1) {
			depth[next] = depth[top] + 1;
			parent[next] = top;
			stack.push(next);
			++child_count[top];
		}
	}
	std::vector<SubTree> sub_trees(n);
	for (auto i = 0; i < n; ++i) if (child_count[i] == 0) {
		stack.push(i);
	}
	while (!stack.empty()) {
		const auto top = stack.top(); stack.pop();
		long long int sum_min_step{ 0 }, sum_back{ 0 }, sum_multiplier{ 0 }, max_need{ 0 }, sum_need{ 0 }, sum_initial_size{ initial_size[top] }, sum_target_size{ target_size[top] };
		for (const auto next: nodes[top]) if (depth[next] > depth[top]) {
			sum_min_step += sub_trees[next].min_step;
			sum_back += sub_trees[next].back_for_minstep;
			sum_multiplier += sub_trees[next].push_back_multiplier;
			max_need = std::max(max_need, sub_trees[next].need_to_push);
			sum_need += sub_trees[next].need_to_push;
			sum_initial_size += sub_trees[next].sum_initial;
			sum_target_size += sub_trees[next].sum_target;
		}
		const auto need_to_push{ std::max(max_need, sum_initial_size - sum_target_size) };
		sum_min_step += need_to_push;
		for (const auto next : nodes[top]) if (depth[next] > depth[top]) {
			sum_min_step += (need_to_push - sub_trees[next].need_to_push) * sub_trees[next].push_back_multiplier;
		}
		sub_trees[top] = SubTree{ sum_min_step, need_to_push, std::max(sum_target_size - sum_initial_size + need_to_push, 0LL),
			sum_multiplier + 1, sum_initial_size, sum_target_size };
		if (parent[top] != -1 && --child_count[parent[top]] == 0) {
			stack.push(parent[top]);
		}
	}
	std::cout << sub_trees[0].min_step << '\n';
}