链接
分析
一开始是打算统计每个sad节点的子树大小,然后在dfs的过程中不断更新答案和子树的大小,后来发现根本不用这么麻烦,直接统计不sad的节点即可,注意在dfs的过程中更新dis。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n, ans, cnt;
int head[N], w[N];
struct edge{
int to, nxt;
ll val;
}e[N << 1];
inline int read(){
int num = 0, t = 1;
char ch = getchar();
while (!isdigit(ch)){
if (ch == '-') t = -1;
ch = getchar();
}
while (isdigit(ch)){
num = (num << 1) + (num << 3) + (ch ^ 48);
ch = getchar();
}
return num * t;
}
inline void add(int u, int v, ll w){
e[++cnt] = {v, head[u], w};
head[u] = cnt;
}
void dfs(int u, int fa, ll dis){
if (dis > w[u]) return;
++ans;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v == fa) continue;
dfs(v, u, max(e[i].val, dis + e[i].val));
}
}
int main() {
n = read();
for (int i = 1; i <= n; ++i)
w[i] = read();
for (int i = 2, x, y; i <= n; ++i) {
x = read(), y = read();
add(i, x, y), add(x, i, y);
}
dfs(1, 0, 0);
printf("%d\n", n - ans);
return 0;
}