Problem p03603 (C++)

Buggy submission (status: Time Limit Exceeded):
// 基本テンプレート

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define repq(i, a, n) for (int(i) = (a); (i) <= (n); (i)++)
#define repr(i, a, n) for (int(i) = (a); (i) >= (n); (i)--)
#define int long long int

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
constexpr ll INF = 1001001001001001LL;
constexpr ll MOD = 1000000007LL;

const int MAXN = 1010;
const int MAXX = 5010;
vector<int> G[MAXN];
int N, x[MAXN], dp[MAXN], dp2[MAXN][MAXX];
bool ok = true;

int solve_dp(vector<int> &a, vector<int> &b, int &lim) {
  int M = a.size();
  rep(i, 0, MAXN) repq(j, 0, lim) dp2[i][j] = INF;
  dp2[0][0] = 0;
  rep(i, 0, M) repq(j, 0, lim) {
    if (dp2[i][j] == INF)
      continue;

    // choose a
    if (j + a[i] <= lim) {
      chmin(dp2[i + 1][j + a[i]], dp2[i][j] + b[i]);
    }

    // choose b
    if (j + b[i] <= lim) {
      chmin(dp2[i + 1][j + b[i]], dp2[i][j] + a[i]);
    }
  }
  return *min_element(dp2[M], dp2[M] + lim + 1);
}

void solve(int p, int par = -1) {
  bool leaf = true;
  vector<int> a, b;
  for (auto to : G[p]) {
    if (to == par)
      continue;
    leaf = false;
    solve(to, p);
    a.push_back(x[to]);
    b.push_back(dp[to]);
  }
  if (leaf)
    dp[p] = 0;
  else {
    int val = solve_dp(a, b, x[p]);
    if (val == INF) {
      ok = false;
      return;
    }
    dp[p] = val;
  }
}

signed main() {
  cin >> N;
  rep(i, 0, N - 1) {
    int p;
    cin >> p;
    p--;
    G[p].push_back(i + 1);
  }
  rep(i, 0, N) {
    cin >> x[i];
    dp[i] = INF;
  }

  solve(0);
  cout << (!ok ? "IMPOSSIBLE" : "POSSIBLE") << endl;
  return 0;
}

Fixed submission:
// 基本テンプレート

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define repq(i, a, n) for (int(i) = (a); (i) <= (n); (i)++)
#define repr(i, a, n) for (int(i) = (a); (i) >= (n); (i)--)
#define int long long int

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
constexpr ll INF = 1001001001001001LL;
constexpr ll MOD = 1000000007LL;

const int MAXN = 1010;
const int MAXX = 5010;
vector<int> G[MAXN];
int N, x[MAXN], dp[MAXN], dp2[MAXN][MAXX];
bool ok = true;

int solve_dp(vector<int> &a, vector<int> &b, int &lim) {
  int M = a.size();
  rep(i, 0, MAXN) repq(j, 0, lim) dp2[i][j] = INF;
  dp2[0][0] = 0;
  rep(i, 0, M) repq(j, 0, lim) {
    if (dp2[i][j] == INF)
      continue;

    // choose a
    if (j + a[i] <= lim) {
      chmin(dp2[i + 1][j + a[i]], dp2[i][j] + b[i]);
    }

    // choose b
    if (j + b[i] <= lim) {
      chmin(dp2[i + 1][j + b[i]], dp2[i][j] + a[i]);
    }
  }
  return *min_element(dp2[M], dp2[M] + lim + 1);
}

void solve(int p, int par = -1) {
  bool leaf = true;
  vector<int> a, b;
  for (auto to : G[p]) {
    if (to == par)
      continue;
    leaf = false;
    solve(to, p);
    a.push_back(x[to]);
    b.push_back(dp[to]);
  }
  if (leaf)
    dp[p] = 0;
  else {
    int val = solve_dp(a, b, x[p]);
    if (val == INF) {
      cout << "IMPOSSIBLE" << endl;
      exit(0);
    }
    dp[p] = val;
  }
}

signed main() {
  cin >> N;
  rep(i, 0, N - 1) {
    int p;
    cin >> p;
    p--;
    G[p].push_back(i + 1);
  }
  rep(i, 0, N) {
    cin >> x[i];
    dp[i] = INF;
  }

  solve(0);
  cout << (!ok ? "IMPOSSIBLE" : "POSSIBLE") << endl;
  return 0;
}