CodeForces - 682C Alyona and the Tree (DFS)

博客介绍了CodeForces的一道竞赛题目,关于一棵带有边权和点权的魔法树,Alyona需要移除使节点悲伤的叶子节点。节点u若其任意子节点到u的距离大于u的点权,则u为悲伤节点。任务是找到最少需要移除的叶子节点数。文章包含问题描述、示例、思路解析以及使用DFS的解题代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Alyona and the Tree

 

Alyona decided to go on a diet and went to the forest to get some apples. There she unexpectedly found a magic rooted tree with root in the vertex 1, every vertex and every edge of which has a number written on.

The girl noticed that some of the tree's vertices are sad, so she decided to play with them. Let's call vertex v sad if there is a vertex u in subtree of vertex vsuch that dist(v, u) > au, where au is the number written on vertex udist(v, u) is the sum of the numbers written on the edges on the path from v to u.

Leaves of a tree are vertices connected to a single vertex by a single edge, but the root of a tree is a leaf if and only if the tree consists of a single vertex — root.

Thus Alyona decided to remove some of tree leaves until there will be no any sad vertex left in the tree. What is the minimum number of leaves Alyona needs to remove?

Input

In the first line of the input integer n (1 ≤ n ≤ 105) is given — the number of vertices in the tree.

In the second line the sequence of n integers a1, a2, ..., an (1 ≤ ai ≤ 109) is given, where ai is the number written on vertex i.

The next n - 1 lines describe tree edges: ith of them consists of two integers pi and ci (1 ≤ pi ≤ n,  - 109 ≤ ci ≤ 109), meaning that there is an edge connecting vertices i + 1 and pi with number ci written on it.

Output

Print the only integer — the minimum number of leaves Alyona needs to remove such that there will be no any sad vertex left in the tree.

Example

Input

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

Output

5

Note

The following image represents possible process of removing leaves from the tree:

 

题目链接:http://codeforces.com/problemset/problem/682/C

题目大意:n节点的树,有边权,点权,现在一些节点是悲伤的,如果这个节点u到其任一祖先节点的距离dis(v,u)大于这点的点权a[u],那么这个点u就是悲伤的,现在问这颗树上有几个节点是悲伤的。

思路:可以转换成解决有几个节点是不悲伤的,如果要满足这个节点是不悲伤的,只需要满足这个点的所有祖先节点到这个节点的dis都小于等于这个点的点权a[u],也就是求其所有祖先到这个点的最大dis小于等于这个节点。可用DFS实现,具体实现见代码。

代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const int N=100005;
ll a[N];
int n,tot,first[N],ans,vis[N]; //ans记录不悲伤的节点数
struct node
{
    int v,nex;
    ll w;
}e[N<<1];
void init()
{
    ans=tot=0;
    memset(first,-1,sizeof(first));
    memset(vis,0,sizeof(vis));
}
void adde(int u,int v,ll w)
{
    e[tot].v=v,e[tot].w=w;
    e[tot].nex=first[u];
    first[u]=tot++;
}
void dfs(int u,ll sum) //传入当前节点编号,到所有祖先的最大dis
{
    if(sum<=a[u]) ans++; //如果满足最大的dis<=a[u],那点u就是不悲伤的点
    else return; //如果不满足的话,这个点就是悲伤点,要删掉这个点,其所有子节点也都不用管了
    vis[u]=1;
    for(int i=first[u];~i;i=e[i].nex) //遍历与点u相连的点
    {
        int v=e[i].v;
        ll w=e[i].w;
        if(!vis[v]) //如果这点还没有标记过,也就是点v是点u的子节点
        dfs(v,max(sum+w,w)); 
    }
}
int main()
{
    scanf("%d",&n);
    init();
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]); //点权
    int v;
    ll w;
    for(int i=2;i<=n;i++)  //存树
    {
        scanf("%d%lld",&v,&w); 
        adde(i,v,w); 
        adde(v,i,w);
    }
    dfs(1,0); 
    printf("%d\n",n-ans);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值