1. 程式人生 > >Codeforces1099D.Sum in the tree(貪心)

Codeforces1099D.Sum in the tree(貪心)

題目連結:傳送門

思路:

  一個節點放的數越大,那麼以它為根的子樹的節點權值之和就越小。

  所以我們要在合法的範圍內,使偶數層節點的權值儘可能地大。也就是說,令它的權值是子節點的最小值,這樣保證了它的子節點權值為正。

  因為奇數層的節點的s已知,所以修改偶數層的節點僅影響,向下一層的節點。(因為再往下的話,路徑上的權值和不隨這個偶數層的節點的權值改變而改變,而是被奇數層截斷了)

程式碼:

#include <bits/stdc++.h>

using namespace std;
const int MAX_N = 1e5 + 5;
const
int INF = 0x3f3f3f3f; int p[MAX_N], s[MAX_N]; int a[MAX_N]; int main() { int N; cin >> N; for (int i = 2; i <= N; i++) scanf("%d", &p[i]); for (int i = 1; i <= N; i++) scanf("%d", &s[i]); for (int i = 2; i <= N; i++) { if (s[i] == -1
) s[i] = INF; else { s[p[i]] = min(s[p[i]], s[i]); } } a[1] = s[1]; for (int i = 2; i <= N; i++) { if (s[i] == INF) { a[i] = 0; continue; } a[i] = s[i] - s[p[i]]; } long long ans = 0; for
(int i = 1; i <= N; i++) { ans += a[i]; if (a[i] < 0) { ans = -1; break; } } cout << ans << endl; return 0; }
View Code