思路:
我们可以发现叶子节点是一定要染的,如果从下往上染没染过的点,不一定是最优的,所以对于其他的结点,我们更新最大染色范围,如果该结点的子节点可以染色到它的话,那么他就不需要再染色,否则它就需要被染色,同时选择子节点内范围最大的点染色,更新最大范围。
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5; vector<int> v[N]; int n, res, k[N]; int dfs(int x, int fa) { int sum = 0; for (auto now : v[x]) sum = max(sum, dfs(now, x)); if (!sum) { res++; return k[x] - 1; } k[fa] = max(k[fa], k[x] - 1); return sum - 1; } int main() { cin >> n; for (int i = 2; i <= n; i++) { int x; cin >> x; v[x].push_back(i); } for (int i = 1; i <= n; i++) cin >> k[i]; dfs(1, 0); cout << res << endl; return 0; }