C. Uncle Bogdan and Country Happiness

code

editorialと同じ変数名にしています

void solve(){
  ll N,M;
  cin>>N>>M;
  
  VI P(N);
  rep(i,N)cin>>P[i];

  VI H(N);
  rep(i,N)cin>>H[i];
  
  VV G(N);
  rep(i,N-1){
    ll a,b;cin>>a>>b;
    a--;b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }

  VI A(N, -1);
  // i以下の部分木の帰宅者の和(何人が通過する?)
  function<ll(ll,ll)> dfs = [&](ll i, ll prev){
    if(A[i]!=-1)return A[i];
    ll sum = P[i];
    for(ll to : G[i]){
      if(to==prev)continue;
      sum += dfs(to, i);
    }
    return A[i]=sum;
  };
  dfs(0, -1);

  rep(i,N){
    // 通過者とハピの偶奇は一致する
    // if(A[i]%2 != H[i]%2){ // これだとH[i]が負のときダメ
    if((A[i]+H[i])%2==0){
      // ok
    }else{
      debug("parity error",i);
      p_no();return;
    }
  }

  // 各点をhappyで通過した「人数」
  VI g(N);
  rep(i,N){
    g[i] = (H[i]+A[i])/2;
  }

  rep(i,N){
    if(0<=g[i] && g[i]<=A[i]){
      // ok
    }else{
      debug("g is contradicted");
      p_no();return;
    }
  }

  // 子供チェック用dfs
  bool ok=true;
  function<void(ll,ll)> DFS = [&](ll i, ll prev){
    ll g_sum=0;
    for(ll to : G[i]){
      if(to==prev)continue;
      g_sum += g[to];
      DFS(to,i);
    }
    if(g_sum>g[i]){
      ok=false;
    }
  };
  DFS(0, -1);
  if(!ok){
    p_no();return;
  }
  p_yes();
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    // input
    ll N; 
    cin>>N;
    
    while(N--)solve();
    
    return 0;
}