Problem p03376 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <iostream>
#define inf 10000000000000
typedef long long ll;
using namespace std;
const int maxN = 55;
const int maxM = 1e6;
int siz[maxN], p[maxN];
ll m[maxN], N, X, D, dp[maxN * maxN];
bool ok[maxN][maxN], in[maxN];
// ll dp[2][maxM];
struct node {
  ll m;
  int siz;
  int idx;
  ll num, d;
} a[maxN], t[maxN];
bool cmp(const node &e1, const node &e2) {
  if (e1.siz * e2.m == e2.siz * e1.m)
    return e1.siz < e2.siz;
  return e1.siz * e2.m > e2.siz * e1.m;
}
void dfs(int u) {
  a[u].siz = 1;
  for (int i = 1; i <= N; ++i) {
    if (ok[u][i]) {
      dfs(i);
      a[u].siz += a[i].siz;
      a[u].m += a[i].m;
    }
  }
  // cout << u << ' ' << a[u].siz << ' ' << a[u].m << endl;
}

int main() {
  // freopen("input.txt", "r", stdin);
  scanf("%lld%lld%lld", &N, &X, &D);
  // cout << D << "&&&&&&&&&&&&&&&&" << endl;
  scanf("%lld", &a[1].m);
  a[1].d = inf;
  for (int i = 2; i <= N; ++i)
    a[i].d = D, a[i].idx = i, scanf("%lld%d", &a[i].m, &p[i]), ok[p[i]][i] = 1,
    a[i].num = max(0ll, D - 50);
  a[1].num = inf;
  dfs(1);
  for (int i = 1; i <= 2500 * 50; ++i)
    dp[i] = inf;
  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= min(50ll, D); j++) {
      for (int k = 2500 * 50; k >= 0; --k) {
        if (k - a[i].siz >= 0)
          dp[k] = min(dp[k], dp[k - a[i].siz] + a[i].m);
      }
    }
  }
  sort(a + 1, a + 1 + N, cmp);
  ll ans = 0;
  for (int i = 0; i <= 2500 * 50; ++i) {
    if (dp[i] > X)
      continue;
    ll x = X - dp[i];
    ll cnt = i;
    for (int j = 1; j <= N; ++j) {
      ll tmp = min(x / a[j].m, a[j].num);
      x -= tmp * a[j].m;
      cnt += tmp * a[j].siz;
    }
    ans = max(ans, cnt);
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <iostream>
#define inf 10000000000000
typedef long long ll;
using namespace std;
const int maxN = 55;
const int maxM = 1e6;
int siz[maxN], p[maxN];
ll m[maxN], N, X, D, dp[maxN * maxN * maxN];
bool ok[maxN][maxN], in[maxN];
// ll dp[2][maxM];
struct node {
  ll m;
  int siz;
  int idx;
  ll num, d;
} a[maxN], t[maxN];
bool cmp(const node &e1, const node &e2) {
  if (e1.siz * e2.m == e2.siz * e1.m)
    return e1.siz < e2.siz;
  return e1.siz * e2.m > e2.siz * e1.m;
}
void dfs(int u) {
  a[u].siz = 1;
  for (int i = 1; i <= N; ++i) {
    if (ok[u][i]) {
      dfs(i);
      a[u].siz += a[i].siz;
      a[u].m += a[i].m;
    }
  }
  // cout << u << ' ' << a[u].siz << ' ' << a[u].m << endl;
}

int main() {
  // freopen("input.txt", "r", stdin);
  scanf("%lld%lld%lld", &N, &X, &D);
  // cout << D << "&&&&&&&&&&&&&&&&" << endl;
  scanf("%lld", &a[1].m);
  a[1].d = inf;
  for (int i = 2; i <= N; ++i)
    a[i].d = D, a[i].idx = i, scanf("%lld%d", &a[i].m, &p[i]), ok[p[i]][i] = 1,
    a[i].num = max(0ll, D - 50);
  a[1].num = inf;
  dfs(1);
  for (int i = 1; i <= 2500 * 50; ++i)
    dp[i] = inf;
  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= min(50ll, D); j++) {
      for (int k = 2500 * 50; k >= 0; --k) {
        if (k - a[i].siz >= 0)
          dp[k] = min(dp[k], dp[k - a[i].siz] + a[i].m);
      }
    }
  }
  sort(a + 1, a + 1 + N, cmp);
  ll ans = 0;
  for (int i = 0; i <= 2500 * 50; ++i) {
    if (dp[i] > X)
      continue;
    ll x = X - dp[i];
    ll cnt = i;
    for (int j = 1; j <= N; ++j) {
      ll tmp = min(x / a[j].m, a[j].num);
      x -= tmp * a[j].m;
      cnt += tmp * a[j].siz;
    }
    ans = max(ans, cnt);
  }
  cout << ans << endl;
  return 0;
}