Problem p03603 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

namespace {

typedef double real;
typedef long long ll;
const int INF = INT_MAX / 4;

template <class T> ostream &operator<<(ostream &os, const vector<T> &vs) {
  if (vs.empty())
    return os << "[]";
  auto i = vs.begin();
  os << "[" << *i;
  for (++i; i != vs.end(); ++i)
    os << " " << *i;
  return os << "]";
}
template <class T> istream &operator>>(istream &is, vector<T> &vs) {
  for (auto it = vs.begin(); it != vs.end(); it++)
    is >> *it;
  return is;
}

int N;
vector<int> P, X;
void input() {
  cin >> N;
  P.resize(N - 1);
  X.resize(N);
  cin >> P;
  cin >> X;
  for (auto &p : P) {
    p--;
  }
}

vector<vector<int>> C;
void solve() {
  C.resize(N);
  for (int i = 1; i < N; i++) {
    C[P[i - 1]].push_back(i);
  }
  // cout << C << endl;

  vector<pair<int, int>> T(N);
  for (auto &t : T)
    t.first = t.second = INF;

  function<pair<int, int>(int)> dfs = [&](int v) -> pair<int, int> {
    if (C[v].empty()) {
      return T[v] = make_pair(0, X[v]);
    }
    if (T[v].first != INF)
      return T[v];
    auto cs = C[v]; // children of v
    vector<pair<int, int>> ds;
    int first_sum = 0;
    int second_sum = 0;
    for (auto c : cs) {
      auto cres = dfs(c);
      ds.push_back(cres);
      first_sum += cres.first;
      second_sum += cres.second;
    }
    if (first_sum > X[v])
      return T[v] = make_pair(INF - 1, INF - 1);
    if (first_sum == X[v])
      return make_pair(first_sum, second_sum);
    vector<int> ss;
    int ss_sum = 0;
    for (auto d : ds) {
      // assert(d.second >= d.first);
      ss.push_back(d.second - d.first);
      ss_sum += d.second - d.first;
    }
    vector<int> dp(X[v] - first_sum + 100, false);
    dp[0] = true;
    int replace_max = 0;
    for (int i = 0; i < ss.size(); i++) {
      for (int k = X[v] - first_sum; k >= 0; k--) {
        int nk = k - ss[i];
        if (nk < 0)
          continue;
        if (dp[nk]) {
          dp[k] = true;
          replace_max = max(replace_max, k);
        }
      }
    }
    // assert(first_sum + replace_max <= X[v]);
    // cout << "v: " << v << " ss: " << ss << " replace_max: " << replace_max <<
    // endl;
    auto ret = make_pair(X[v], second_sum - replace_max);
    // cout << "ret: " << ret.first << "&" << ret.second << endl;
    // cout << first_sum << " " << second_sum << endl;
    if (ret.first > ret.second)
      swap(ret.first, ret.second);
    return T[v] = ret;
  };
  auto t = dfs(0);
  // for (int i = 0; i < N; i++) {
  //     auto t = T[i];
  //     cout << i << " : " << t.first << " " << t.second << endl;
  // }
  // cout << t.first << " " << t.second << endl;
  if (t.second < INF - 2) {
    cout << "POSSIBLE" << endl;
  } else {
    cout << "IMPOSSIBLE" << endl;
  }
}
} // namespace

int main() {
  input();
  solve();
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

namespace {

typedef double real;
typedef long long ll;
const int INF = INT_MAX / 4;

template <class T> ostream &operator<<(ostream &os, const vector<T> &vs) {
  if (vs.empty())
    return os << "[]";
  auto i = vs.begin();
  os << "[" << *i;
  for (++i; i != vs.end(); ++i)
    os << " " << *i;
  return os << "]";
}
template <class T> istream &operator>>(istream &is, vector<T> &vs) {
  for (auto it = vs.begin(); it != vs.end(); it++)
    is >> *it;
  return is;
}

int N;
vector<int> P, X;
void input() {
  cin >> N;
  P.resize(N - 1);
  X.resize(N);
  cin >> P;
  cin >> X;
  for (auto &p : P) {
    p--;
  }
}

vector<vector<int>> C;
void solve() {
  C.resize(N);
  for (int i = 1; i < N; i++) {
    C[P[i - 1]].push_back(i);
  }
  // cout << C << endl;

  vector<pair<int, int>> T(N);
  for (auto &t : T)
    t.first = t.second = INF;

  function<pair<int, int>(int)> dfs = [&](int v) -> pair<int, int> {
    if (C[v].empty()) {
      return T[v] = make_pair(0, X[v]);
    }
    if (T[v].first != INF)
      return T[v];
    auto cs = C[v]; // children of v
    vector<pair<int, int>> ds;
    int first_sum = 0;
    int second_sum = 0;
    for (auto c : cs) {
      auto cres = dfs(c);
      if (cres.first == INF - 1)
        return make_pair(INF - 1, INF - 1);
      ds.push_back(cres);
      first_sum += cres.first;
      second_sum += cres.second;
    }
    if (first_sum > X[v])
      return T[v] = make_pair(INF - 1, INF - 1);
    if (first_sum == X[v])
      return make_pair(first_sum, second_sum);
    vector<int> ss;
    int ss_sum = 0;
    for (auto d : ds) {
      // assert(d.second >= d.first);
      ss.push_back(d.second - d.first);
      ss_sum += d.second - d.first;
    }
    vector<int> dp(X[v] - first_sum + 100, false);
    dp[0] = true;
    int replace_max = 0;
    for (int i = 0; i < ss.size(); i++) {
      for (int k = X[v] - first_sum; k >= 0; k--) {
        int nk = k - ss[i];
        if (nk < 0)
          continue;
        if (dp[nk]) {
          dp[k] = true;
          replace_max = max(replace_max, k);
        }
      }
    }
    // assert(first_sum + replace_max <= X[v]);
    // cout << "v: " << v << " ss: " << ss << " replace_max: " << replace_max <<
    // endl;
    auto ret = make_pair(X[v], second_sum - replace_max);
    // cout << "ret: " << ret.first << "&" << ret.second << endl;
    // cout << first_sum << " " << second_sum << endl;
    if (ret.first > ret.second)
      swap(ret.first, ret.second);
    return T[v] = ret;
  };
  auto t = dfs(0);
  // for (int i = 0; i < N; i++) {
  //     auto t = T[i];
  //     cout << i << " : " << t.first << " " << t.second << endl;
  // }
  // cout << t.first << " " << t.second << endl;
  if (t.second < INF - 2) {
    cout << "POSSIBLE" << endl;
  } else {
    cout << "IMPOSSIBLE" << endl;
  }
}
} // namespace

int main() {
  input();
  solve();
  return 0;
}