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

猜你喜欢

转载自www.cnblogs.com/Lubixiaosi-Zhaocao/p/10236548.html