题目链接:传送门
思路:
一个节点放的数越大,那么以它为根的子树的节点权值之和就越小。
所以我们要在合法的范围内,使偶数层节点的权值尽可能地大。也就是说,令它的权值是子节点的最小值,这样保证了它的子节点权值为正。
因为奇数层的节点的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; }