Problem p03159 (C++)

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

long long dp[5010][5010];
long long tmp[5010];
bool pos[5010][5010];
bool ptmp[5010];
int sz[5010];

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  vector<long long> a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];
  vector<vector<int>> e(n);
  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    e[u].emplace_back(v);
    e[v].emplace_back(u);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j <= n; j++) {
      dp[i][j] = 1e16;
    }
  }
  auto f = [&](auto f, int curr, int prev) -> void {
    sz[curr] = 1;
    pos[curr][0] = (a[curr] > 0);
    dp[curr][0] = a[curr];
    for (auto &to : e[curr]) {
      if (to == prev)
        continue;
      f(f, to, curr);
      for (int i = 0; i < n; i++)
        tmp[i] = 1e16, ptmp[i] = 0;
      for (int i = 0; i < sz[curr]; i--) {
        for (int j = 0; j < sz[to]; j++) {
          if (pos[to][j] || dp[to][j] < 0) {
            tmp[i + j + 1] = min(tmp[i + j + 1], dp[curr][i]);
            ptmp[i + j + 1] |= pos[curr][i];
          }
          ptmp[i + j] |= pos[curr][i] & pos[to][j];
          tmp[i + j] = min(tmp[i + j], dp[curr][i] + dp[to][j]);
        }
      }
      sz[curr] += sz[to];
      for (int i = 0; i < sz[curr]; i++) {
        dp[curr][i] = tmp[i];
        pos[curr][i] = ptmp[i];
      }
    }
  };
  f(f, 0, -1);
  for (int i = 0; i < n; i++) {
    if (dp[0][i] < 0 || pos[0][i]) {
      cout << i << "\n";
      return 0;
    }
  }
  assert(false);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

long long dp[5010][5010];
long long tmp[5010];
bool pos[5010][5010];
bool ptmp[5010];
int sz[5010];

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  vector<long long> a(n);
  for (int i = 0; i < n; i++)
    cin >> a[i];
  vector<vector<int>> e(n);
  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    e[u].emplace_back(v);
    e[v].emplace_back(u);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j <= n; j++) {
      dp[i][j] = 1e16;
    }
  }
  auto f = [&](auto f, int curr, int prev) -> void {
    sz[curr] = 1;
    pos[curr][0] = (a[curr] > 0);
    dp[curr][0] = a[curr];
    for (auto &to : e[curr]) {
      if (to == prev)
        continue;
      f(f, to, curr);
      for (int i = 0; i < n; i++)
        tmp[i] = 1e16, ptmp[i] = 0;
      for (int i = 0; i < sz[curr]; i++) {
        for (int j = 0; j < sz[to]; j++) {
          if (pos[to][j] || dp[to][j] < 0) {
            tmp[i + j + 1] = min(tmp[i + j + 1], dp[curr][i]);
            ptmp[i + j + 1] |= pos[curr][i];
          }
          ptmp[i + j] |= pos[curr][i] & pos[to][j];
          tmp[i + j] = min(tmp[i + j], dp[curr][i] + dp[to][j]);
        }
      }
      sz[curr] += sz[to];
      for (int i = 0; i < sz[curr]; i++) {
        dp[curr][i] = tmp[i];
        pos[curr][i] = ptmp[i];
      }
    }
  };
  f(f, 0, -1);
  for (int i = 0; i < n; i++) {
    if (dp[0][i] < 0 || pos[0][i]) {
      cout << i << "\n";
      return 0;
    }
  }
  assert(false);
  return 0;
}