F - Alyona and the Tree CodeForces - 682C DFS

Alyona and the Tree CodeForces - 682C DFS

题目大意:有一棵树,节点有权值,边也有权值,问满足dist(v, u) >a[u]的节点有多少个,dist(v, u)是说u,v两个节点之间的距离,a[u]是说这个节点的权值。需要注意的事情是这棵树有根1。
题目分析:一开始的时候,有个疑问是对于一棵子树,如果它的根去掉了,那么他的子树是往上接还是直接去掉,很迷,后来仔细看了看样例,发现是直接去掉了。
这题一个很重要的点,就是当dfs的时候,把路径值累加起来,但是有负数,这样就会出现加到一个节点,它本身比a[u]大,但是加上之前的负数就变小了,这样我们就错加了。所以当我们累加值sum<0时,把它变为0就可以了。
样例:
9
88 22 83 14 95 91 98 53 11
3 24
7 -8
1 67
1 64
9 65
5 12
6 -80
3 8
输出:5
这里写图片描述
代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1e5 + 10;

struct node {
   int v;
   ll w;
};
int data[maxn], ans;
vector<node> Edge[maxn];

void dfs(int root, int pre, ll sum) {
   ans++;
//   printf("!!!%d %d %d\n", root, pre, ans);
   for(int i = 0; i < Edge[root].size(); i++) {
       int to = Edge[root][i].v;
       if(to != pre) {
            if(sum < 0) sum = 0;
            if(sum + Edge[root][i].w <= data[to])
            dfs(to, root, sum + Edge[root][i].w);
       }
   }
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
         scanf("%d", &data[i + 1]);
    }
    for(int i = 1; i < n; i++) {
        int v;
        ll w;
        scanf("%d %lld", &v, &w);
        Edge[v].push_back((node) {i + 1, w});
        Edge[i + 1].push_back((node) {v, w});
    }

    ans = 0;
    dfs(1, -1, 0);
    printf("%d\n", n - ans);
}

猜你喜欢

转载自blog.csdn.net/deerly_/article/details/80957402