Problem p03603 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#define N 1234
#define NN 5678
template <typename T> inline void read(T &x) {
  x = 0;
  char c = getchar();
  bool flag = false;
  while (!isdigit(c)) {
    if (c == '-')
      flag = true;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 1) + (x << 3) + (c ^ 48);
    c = getchar();
  }
  if (flag)
    x = -x;
}
using namespace std;
const int inf = 7654321;
inline void MIN(int &a, int b) {
  if (b < a)
    a = b;
}
int n;
struct edge {
  int nxt, to;
} e[N << 1];
int head[N], ecnt;
inline void addedge(int from, int to) {
  e[++ecnt] = (edge){head[from], to};
  head[from] = ecnt;
}
int fa[N];
int val[N];
int f[N][2], g[N], og[N];
inline void calc(int cur, int t) {
  memset(g, 0x3f, sizeof(g));
  g[0] = 0;
  for (signed int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    memcpy(og, g, sizeof(g));
    memset(g, 0x3f, sizeof(g));
    for (signed int j = val[cur]; ~j; --j) {
      if (j >= val[to] && og[j - val[to]] <= inf)
        MIN(g[j], og[j - val[to]] + f[to][t]);
      if (j >= f[to][t ^ 1] && og[j - f[to][t ^ 1]] <= inf)
        MIN(g[j], og[j - f[to][t ^ 1]] + val[to]);
    }
  }
  for (signed int j = 0; j <= val[cur]; ++j)
    MIN(f[cur][t], g[j]);
}
void dfs(int cur) {
  for (signed int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    dfs(to);
  }
  calc(cur, 0);
  calc(cur, 1);
  if (f[cur][0] > inf && f[cur][1] > inf) {
    puts("IMPOSSIBLE");
    exit(0);
  }
}

int main() {
  memset(f, 0x3f, sizeof(f));
  read(n);
  for (signed int i = 2; i <= n; ++i)
    read(fa[i]), addedge(fa[i], i);
  for (signed int i = 1; i <= n; ++i)
    read(val[i]);
  dfs(1);
  puts("POSSIBLE");
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#define N 1234
#define NN 5678
template <typename T> inline void read(T &x) {
  x = 0;
  char c = getchar();
  bool flag = false;
  while (!isdigit(c)) {
    if (c == '-')
      flag = true;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 1) + (x << 3) + (c ^ 48);
    c = getchar();
  }
  if (flag)
    x = -x;
}
using namespace std;
const int inf = 7654321;
inline void MIN(int &a, int b) {
  if (b < a)
    a = b;
}
int n;
struct edge {
  int nxt, to;
} e[N << 1];
int head[N], ecnt;
inline void addedge(int from, int to) {
  e[++ecnt] = (edge){head[from], to};
  head[from] = ecnt;
}
int fa[N];
int val[N];
int f[N][2], g[NN], og[NN];
inline void calc(int cur, int t) {
  memset(g, 0x3f, sizeof(g));
  g[0] = 0;
  for (signed int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    memcpy(og, g, sizeof(g));
    memset(g, 0x3f, sizeof(g));
    for (signed int j = val[cur]; ~j; --j) {
      if (j >= val[to] && og[j - val[to]] <= inf)
        MIN(g[j], og[j - val[to]] + f[to][t]);
      if (j >= f[to][t ^ 1] && og[j - f[to][t ^ 1]] <= inf)
        MIN(g[j], og[j - f[to][t ^ 1]] + val[to]);
    }
  }
  for (signed int j = 0; j <= val[cur]; ++j)
    MIN(f[cur][t], g[j]);
}
void dfs(int cur) {
  for (signed int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    dfs(to);
  }
  calc(cur, 0);
  calc(cur, 1);
  if (f[cur][0] > inf && f[cur][1] > inf) {
    puts("IMPOSSIBLE");
    exit(0);
  }
}

int main() {
  memset(f, 0x3f, sizeof(f));
  read(n);
  for (signed int i = 2; i <= n; ++i)
    read(fa[i]), addedge(fa[i], i);
  for (signed int i = 1; i <= n; ++i)
    read(val[i]);
  dfs(1);
  puts("POSSIBLE");
  return 0;
}