Language: C++

#pragma GCC target ("avx2")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include <unordered_set>
#include <unordered_map>
#include <random>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
const int dx[4]={ 1,0,-1,0 };
const int dy[4]={ 0,1,0,-1 };

int N;
ll A[5000];
vector<int> E[5000], chi[5000];

void dfs(int v, int p){
    rep(i, E[v].size()){
        if(E[v][i] == p) continue;
        dfs(E[v][i], v);
        chi[v].pb(E[v][i]);
    }
}

bool solveB(int, int, int);

unordered_map<int, ll> dp[5000][5000];
ll solve(int v, int n, int e){
    if(e == chi[v].size()){
        if(n == 0) return A[v];
        else return 1e18L;
    }
    if(dp[v][n].count(e)) return dp[v][n][e];
    ll ret = 1e18L;
    rep(i, n+1){
        ret = min(ret, solve(chi[v][e], n-i, 0) + solve(v, i, e+1));
        if(n-i > 0)
            ret = min(ret, solve(chi[v][e], n-i-1, 0) + solve(v, i, e+1));
        if(A[chi[v][e]] > 0 && n-i > 0 && solveB(chi[v][e], n-i-1, 0))
            ret = min(ret, solve(v, i, e+1));
    }
    return dp[v][n][e] = ret;
}

unordered_map<int, bool> dpB[5000][5000];
bool solveB(int v, int n, int e){
    if(e == chi[v].size()){
        if(n == 0) return true;
        else return false;
    }
    if(dpB[v][n].count(e)) return dpB[v][n][e];
    bool ret = false;
    rep(i, n+1){
        if(n-i > 0)
            ret |= (solve(chi[v][e], n-i-1, 0) < 0) && solveB(v, i, e+1);
        if(A[chi[v][e]] > 0 && n-i > 0)
            ret |= solveB(chi[v][e], n-i-1, 0) && solveB(v, i, e+1);
        if(A[chi[v][e]] > 0)
            ret |= solveB(chi[v][e], n-i, 0) && solveB(v, i, e+1);
    }
    return dpB[v][n][e] = ret;
}

signed main(){
    cin >> N;
    rep(i, N) cin >> A[i];
    rep(i, N-1){
        int u, v;
        cin >> u >> v;
        u--; v--;
        E[u].pb(v);
        E[v].pb(u);
    }
    dfs(0, -1);
    
    for(int i=N; i>=1; i--){
        if(A[0] > 0){
            if(solve(0, i-1, 0) >= 0 && solveB(0, i-1, 0) == false){
                cout << i << endl;
                exit(0);
            }
        }
        else{
            if(solve(0, i-1, 0) >= 0){
                cout << i << endl;
                exit(0);
            }
        }
    }
    cout << 0 << endl;
}

Compiler output:
In file included from /usr/include/c++/14/string:43,
                 from /usr/include/c++/14/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:52,
                 from a.cc:4:
/usr/include/c++/14/bits/allocator.h: In destructor 'std::_Vector_base<int, std::allocator<int> >::_Vector_impl::~_Vector_impl()':
/usr/include/c++/14/bits/allocator.h:182:7: error: inlining failed in call to 'always_inline' 'std::allocator< <template-parameter-1-1> >::~allocator() noexcept [with _Tp = int]': target specific option mismatch
  182 |       ~allocator() _GLIBCXX_NOTHROW { }
      |       ^
In file included from /usr/include/c++/14/vector:66,
                 from /usr/include/c++/14/functional:64,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:53:
/usr/include/c++/14/bits/stl_vector.h:132:14: note: called from here
  132 |       struct _Vector_impl
      |              ^~~~~~~~~~~~