codeforces 682C. Alyona and the Tree

来源:互联网 发布:万网云新建数据库 编辑:程序博客网 时间:2024/06/06 18:50

codeforces 682C. Alyona and the Tree

题意

有一颗树,树上的点和边都有权值。要求删除树上若干节点,使得树上每个节点u到其子树上的节点v的dis(u,v)a(u)。问最少需要删除多少个节点。

思路

类似与最大连续子段和的思想,对于每个节点是否要保留,在于是否有从根节点方向到以他为结尾的树链的权值比其点权大,有则删除该子树,无则保留该节点。

code

#include <vector>#include <iostream>#include <algorithm>using namespace std;#define MAXN (100000 + 5)#define INF  (999999999)int n;int a[MAXN];int c[MAXN], dp[MAXN], ans;std::vector<pair<int, int> > v[MAXN];void CN (int rt) {  if (v[rt].size() == 0) {    c[rt] = 1;    return;  }  c[rt] = 1;  for (int i=0; i<v[rt].size(); i++) {    CN(v[rt][i].first);    c[rt] += c[v[rt][i].first];  }}void DP (int rt) {  if (v[rt].size() == 0) {    return ;  }  for (int i=0; i<v[rt].size(); i++) {    pair<int, int> th = v[rt][i];    if (dp[rt] > 0) dp[th.first] = dp[rt] + th.second;    else dp[th.first] = th.second;    if (dp[th.first] <= a[th.first]) {      DP(th.first);    } else {      ans += c[th.first];    }  }}int main () {  ios::sync_with_stdio(false);  cin >> n;  for (int i=1; i<=n; i++) {    cin >> a[i];  }  int tmpa, tmpb;  for (int i=2; i<=n; i++) {    cin >> tmpa >> tmpb;    v[tmpa].push_back(make_pair(i, tmpb));  }  ans = 0;  CN(1);  DP(1);  cout << ans << endl;  return 0;}
0 0