Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- template<typename T>
- void relax_min(T& cur, T val) {
- cur = min(cur, val);
- }
- template<typename T>
- void relax_max(T& cur, T val) {
- cur = max(cur, val);
- }
- #define int li
- //const int mod = 1000000007;
- vector<vector<int>> g;
- vector<int> cnt;
- vector<int> dp_all, dp_stay;
- vector<int> a;
- int k;
- struct DP {
- int dp_all, dp_stay, cnt;
- int to;
- bool operator < (const DP& ot) const {
- return dp_all + cnt * 2 < ot.dp_all + ot.cnt * 2;
- }
- };
- DP merge(const DP& l, const DP& r) {
- if (l.cnt == 0) {
- return r;
- }
- if (r.cnt == 0) {
- return l;
- }
- DP res = {min(l.dp_all, r.dp_all - 2 * l.cnt), -1, l.cnt + r.cnt, -1};
- return res;
- }
- void dfs(int v, int p) {
- cnt[v] = 1;
- vector<DP> dps;
- for (int to : g[v]) {
- if (to == p) {
- continue;
- }
- dfs(to, v);
- cnt[v] += cnt[to];
- dps.push_back({dp_all[to], dp_stay[to], cnt[to], to});
- }
- sort(all(dps));
- dp_all[v] = min(a[v], a[v] + k - 2 * cnt[v]);
- dp_stay[v] = -(int)1e18;
- if (dps.empty()) {
- dp_stay[v] = a[v];
- return;
- }
- vector<DP> pref_dp(dps.size() + 1, {0, 0, 0, -1});
- auto suf_dp = pref_dp;
- for (int i = 0; i < dps.size(); ++i) {
- pref_dp[i + 1] = merge(pref_dp[i], dps[i]);
- }
- for (int i = (int)dps.size() - 1; i >= 0; --i) {
- suf_dp[i] = merge(dps[i], suf_dp[i + 1]);
- }
- relax_min(dp_all[v], pref_dp.back().dp_all - 1);
- for (int i = 0; i < dps.size(); ++i) {
- DP cur_dp = merge(pref_dp[i], suf_dp[i + 1]);
- int t = dps[i].dp_stay - 2 * cur_dp.cnt;
- if (dps.size() > 1) {
- relax_min(t, cur_dp.dp_all);
- }
- t = min(t - 1, a[v] + k - 2 * (cnt[v] - cnt[dps[i].to]));
- t = min(t, a[v]);
- relax_max(dp_stay[v], t);
- }
- //cout << v << " " << dp_all[v] << " " << dp_stay[v] << endl;
- }
- void solve(__attribute__((unused)) bool read) {
- int n;
- cin >> n >> k;
- cnt.assign(n, 0);
- g.resize(n);
- dp_all.resize(n);
- dp_stay.resize(n);
- for (int i = 1; i < n; ++i) {
- int x, y;
- cin >> x >> y;
- --x; --y;
- g[x].push_back(y);
- g[y].push_back(x);
- }
- a.resize(n);
- for (int i = 0; i < n; ++i) {
- cin >> a[i];
- }
- dfs(0, 0);
- int res = dp_stay[0];
- if (res < 0) {
- res = -1;
- }
- cout << res << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement