題意node
給一棵\(n\)節點的樹,每一個節點有\(a[i]\)我的住,他們從\(1\)號節點回家,回家路上可能從開心的狀態變成不開心的狀態(但不能夠由不開心變爲開心),每一個節點有個探測器,會探測通過該節點開心的人數減不開心的人數,而預期值爲\(h[i]\),問是否可能存在一種狀況,使得全部節點的探測值等於真實值ios
分析c++
先想一下思路:咱們能夠發現葉子節點的人數開心人數和不開心人數,開心人數必定是從\(1\)號節點一直開心走回家的,不開心的人可能在路中間是開心的,那麼咱們不妨將題目轉換爲每一個人從家出發到\(1\)號節點,他可能一開始是不開心的,他能夠從不開心變爲開心,但不會從開心變爲不開心,那麼對於一個節點,統計它的兒子節點的開心人數和不開心人數,而後不妨設該節點的全部人都是不開心,設\(x\)爲開心的人數,\(y\)爲不開心的人數,\(tot\)爲通過該節點的總人數那麼有方程spa
而後判斷便可code
#pragma GCC optimize(3, "Ofast", "inline") #include <bits/stdc++.h> #define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define ll long long #define int ll #define ls st<<1 #define rs st<<1|1 #define pii pair<int,int> #define rep(z, x, y) for(int z=x;z<=y;++z) #define repd(z, x, y) for(int z=x;z>=y;--z) #define com bool operator<(const node &b)const using namespace std; mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count()); const int maxn = (ll) 3e5 + 5; const int mod = 998244353; const int inf = 0x3f3f3f3f; int T = 1; vector<int> v[maxn]; int a[maxn]; int h[maxn]; bool flag; pii dfs(int now, int pre) { if (!flag) return {0, 0}; pii p = {0, a[now]}; for (auto &to:v[now]) { if (to == pre) continue; pii tmp = dfs(to, now); p.first += tmp.first; p.second += tmp.second; } int x = p.first + p.second + h[now]; if (x & 1) { flag = false; return {0, 0}; } x /= 2; if (x < p.first || x > p.first + p.second) { flag = false; return {0, 0}; } return pii{x, p.first + p.second - x}; } void solve() { int n, m; cin >> n >> m; rep(i, 1, n) { cin >> a[i]; v[i].clear(); } rep(i, 1, n)cin >> h[i]; rep(i, 1, n - 1) { int x, y; cin >> x >> y; v[x].push_back(y); v[y].push_back(x); } flag = true; dfs(1, 0); if (flag) cout << "YES\n"; else cout << "NO\n"; } signed main() { start; cin >> T; while (T--) solve(); return 0; }