Problem p03159 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

using std::cerr;
using std::cin;
using std::cout;
using std::endl;

using std::bitset;
using std::deque;
using std::iterator;
using std::map;
using std::multimap;
using std::multiset;
using std::pair;
using std::queue;
using std::set;
using std::stack;
using std::string;
using std::vector;

using std::fill;
using std::ios_base;
using std::max_element;
using std::min_element;
using std::reverse;
using std::sort;
using std::stable_sort;
using std::swap;
using std::unique;

using std::fixed;
using std::setprecision;

long long min(long long a, long long b) { return a < b ? a : b; }
long long min(int a, long long b) { return a < b ? a : b; }
long long min(long long a, int b) { return a < b ? a : b; }
long long min(int a, int b) { return a < b ? a : b; }

long long max(long long a, long long b) { return a > b ? a : b; }
long long max(int a, long long b) { return a > b ? a : b; }
long long max(long long a, int b) { return a > b ? a : b; }
long long max(int a, int b) { return a > b ? a : b; }

#define int long long

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<long long> vl;
typedef string S;

#define F(i, n) for (int(i) = 0; (i) != (n); (i)++)
#define fi first
#define se second
#define re return
#define all(x) (x).begin(), (x).end()

const long long INF = 1e18;
const int N = 10100;
const int MOD = 1e9 + 7;
const double eps = 1e-8;

int n;
int a[N];
vector<int> graph[N];
int dp[2][N][N / 2];
int last_dinamics[N];
int last_state[N];
int tmp = 0;

void Merge(int p1, int p2) {
  for (int a = 0; a <= last_state[p1]; a++) {
    for (int b = 0; b <= last_state[p2]; b++) {
      dp[0][tmp][a + b] = min(dp[0][tmp][a + b], dp[0][p1][a] + dp[0][p2][b]);
      if (dp[0][p2][b] < INF)
        dp[0][tmp][a + b + 1] = min(dp[0][tmp][a + b + 1], dp[0][p1][a]);
      if (dp[1][p2][b] < 0)
        dp[0][tmp][a + b + 1] = min(dp[0][tmp][a + b + 1], dp[0][p1][a]);
      dp[1][tmp][a + b] =
          min(dp[1][tmp][a + b], min(dp[0][p1][a], dp[1][p1][a]) +
                                     min(dp[0][p2][b], dp[1][p2][b]));
      if (dp[0][p2][b] < INF)
        dp[1][tmp][a + b + 1] =
            min(dp[1][tmp][a + b + 1], min(dp[0][p1][a], dp[1][p1][a]));
      if (dp[1][p2][b] < 0)
        dp[1][tmp][a + b + 1] =
            min(dp[1][tmp][a + b + 1], min(dp[0][p1][a], dp[1][p1][a]));
    }
  }
  last_state[tmp] = last_state[p1] + last_state[p2] + 1;
}

void dfs(int v, int parent) {
  int merge1 = tmp;
  dp[0][tmp][0] = 0, dp[1][tmp][0] = 0;
  tmp++;
  for (auto u : graph[v])
    if (u != parent) {
      dfs(u, v);
      int merge2 = last_dinamics[u];
      Merge(merge1, merge2);
      merge1 = tmp;
      tmp++;
    }
  tmp--;
  for (int i = 0; i < n + 100; i++) {
    dp[1][tmp][i] = min(dp[1][tmp][i] + a[v], INF);
    dp[0][tmp][i] = min(dp[0][tmp][i] + a[v], INF);
  }
  if (a[v] < 0) {
    for (int i = 0; i < n + 100; i++)
      dp[0][tmp][i] = INF;
  }
  last_dinamics[v] = tmp;
  tmp++;
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = 0; i < 2 * n + 100; i++) {
    for (int j = 0; j < n + 100; j++) {
      dp[0][i][j] = INF, dp[1][i][j] = INF;
    }
  }
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  for (int i = 0; i + 1 < n; i++) {
    int v, u;
    cin >> v >> u;
    v--, u--;
    graph[v].push_back(u);
    graph[u].push_back(v);
  }
  dfs(0, -1);
  long long ans = n - 1;
  for (int i = 0; i < n - 1; i++) {
    // cout << dp[1][tmp - 1][i] << " " << dp[0][tmp - 1][i] << "\n";
    if (dp[1][tmp - 1][i] < 0)
      ans = min(ans, i);
    if (dp[0][tmp - 1][i] < INF)
      ans = min(ans, i);
  }
  cout << ans;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

using std::cerr;
using std::cin;
using std::cout;
using std::endl;

using std::bitset;
using std::deque;
using std::iterator;
using std::map;
using std::multimap;
using std::multiset;
using std::pair;
using std::queue;
using std::set;
using std::stack;
using std::string;
using std::vector;

using std::fill;
using std::ios_base;
using std::max_element;
using std::min_element;
using std::reverse;
using std::sort;
using std::stable_sort;
using std::swap;
using std::unique;

using std::fixed;
using std::setprecision;

long long min(long long a, long long b) { return a < b ? a : b; }
long long min(int a, long long b) { return a < b ? a : b; }
long long min(long long a, int b) { return a < b ? a : b; }
long long min(int a, int b) { return a < b ? a : b; }

long long max(long long a, long long b) { return a > b ? a : b; }
long long max(int a, long long b) { return a > b ? a : b; }
long long max(long long a, int b) { return a > b ? a : b; }
long long max(int a, int b) { return a > b ? a : b; }

#define int long long

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<long long> vl;
typedef string S;

#define F(i, n) for (int(i) = 0; (i) != (n); (i)++)
#define fi first
#define se second
#define re return
#define all(x) (x).begin(), (x).end()

const long long INF = 1e18;
const int N = 10110;
const int MOD = 1e9 + 7;
const double eps = 1e-8;

int n;
int a[N];
vector<int> graph[N];
int dp[2][N][N / 2];
int last_dinamics[N];
int last_state[N];
int tmp = 0;

void Merge(int p1, int p2) {
  for (int a = 0; a <= last_state[p1]; a++) {
    for (int b = 0; b <= last_state[p2]; b++) {
      dp[0][tmp][a + b] = min(dp[0][tmp][a + b], dp[0][p1][a] + dp[0][p2][b]);
      if (dp[0][p2][b] < INF)
        dp[0][tmp][a + b + 1] = min(dp[0][tmp][a + b + 1], dp[0][p1][a]);
      if (dp[1][p2][b] < 0)
        dp[0][tmp][a + b + 1] = min(dp[0][tmp][a + b + 1], dp[0][p1][a]);
      dp[1][tmp][a + b] =
          min(dp[1][tmp][a + b], min(dp[0][p1][a], dp[1][p1][a]) +
                                     min(dp[0][p2][b], dp[1][p2][b]));
      if (dp[0][p2][b] < INF)
        dp[1][tmp][a + b + 1] =
            min(dp[1][tmp][a + b + 1], min(dp[0][p1][a], dp[1][p1][a]));
      if (dp[1][p2][b] < 0)
        dp[1][tmp][a + b + 1] =
            min(dp[1][tmp][a + b + 1], min(dp[0][p1][a], dp[1][p1][a]));
    }
  }
  last_state[tmp] = last_state[p1] + last_state[p2] + 1;
}

void dfs(int v, int parent) {
  int merge1 = tmp;
  dp[0][tmp][0] = 0, dp[1][tmp][0] = 0;
  tmp++;
  for (auto u : graph[v])
    if (u != parent) {
      dfs(u, v);
      int merge2 = last_dinamics[u];
      Merge(merge1, merge2);
      merge1 = tmp;
      tmp++;
    }
  tmp--;
  for (int i = 0; i < n + 100; i++) {
    dp[1][tmp][i] = min(dp[1][tmp][i] + a[v], INF);
    dp[0][tmp][i] = min(dp[0][tmp][i] + a[v], INF);
  }
  if (a[v] < 0) {
    for (int i = 0; i < n + 100; i++)
      dp[0][tmp][i] = INF;
  }
  last_dinamics[v] = tmp;
  tmp++;
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = 0; i < 2 * n + 100; i++) {
    for (int j = 0; j < n + 100; j++) {
      dp[0][i][j] = INF, dp[1][i][j] = INF;
    }
  }
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  for (int i = 0; i + 1 < n; i++) {
    int v, u;
    cin >> v >> u;
    v--, u--;
    graph[v].push_back(u);
    graph[u].push_back(v);
  }
  dfs(0, -1);
  long long ans = n - 1;
  for (int i = 0; i < n - 1; i++) {
    // cout << dp[1][tmp - 1][i] << " " << dp[0][tmp - 1][i] << "\n";
    if (dp[1][tmp - 1][i] < 0)
      ans = min(ans, i);
    if (dp[0][tmp - 1][i] < INF)
      ans = min(ans, i);
  }
  cout << ans;
}