Codeforces1099D.Sum in the tree(貪心)
阿新 • • 發佈:2019-01-07
題目連結:傳送門
思路:
一個節點放的數越大,那麼以它為根的子樹的節點權值之和就越小。
所以我們要在合法的範圍內,使偶數層節點的權值儘可能地大。也就是說,令它的權值是子節點的最小值,這樣保證了它的子節點權值為正。
因為奇數層的節點的s已知,所以修改偶數層的節點僅影響,向下一層的節點。(因為再往下的話,路徑上的權值和不隨這個偶數層的節點的權值改變而改變,而是被奇數層截斷了)
程式碼:
#include <bits/stdc++.h> using namespace std; const int MAX_N = 1e5 + 5; constView Codeint 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; }