链接
https://codeforces.com/contest/1388/problem/C
题意
n n n 个点的树形图,树根为 1 1 1,有 m m m 个人开始时在树根,心情都为好,各自回家
p i p_i pi 表示点 i i i是 p i p_i pi 个人的家, h i h_i hi 表示经过点 i i i 的人中心情好的人与心情不好的人的差
每个人经过任意点都有可能变成心情不好,心情不好后无法改变心情
问对于 i ( 1 ≤ i ≤ n ) i(1\le i\le n) i(1≤i≤n) 是否都能与 h i h_i hi 相等
思路
自下而上考虑
设 a i a_i ai 为经过 i i i 但 i i i 不是家的心情好的人, b i b_i bi 为经过 i i i 但 i i i 不是家的心情不好的人
因此对于每个点 i i i, p i + b i p_i+b_i pi+bi 个人心情可好可不好,假设他们心情都不好
那么对于 a i + x − ( p i + b i − x ) = h i a_i+x-(p_i+b_i-x)=h_i ai+x−(pi+bi−x)=hi,如果 h i + p i + b i − a i h_i+p_i+b_i-a_i hi+pi+bi−ai 为奇数,则无解,否则算出 x x x, a i + x a_i+x ai+x 为所有经过点 i i i 的心情好的人, p i + b i − x p_i+b_i-x pi+bi−x 为所有经过点 i i i 的心情不好的人,判断是不是都为正即可
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,a[N],h[N],p[N];
vector<int> G[N];
bool dfs(int u,int fa) {
for(auto v:G[u]) {
if(v==fa) continue;
if(dfs(v,u)==false) return false;
a[u]+=a[v],p[u]+=p[v];
}
if((p[u]+h[u]-a[u])&1) return false;
int x=(h[u]+p[u]-a[u])/2;
if(x<0||p[u]-x<0) return false;
a[u]+=x,p[u]-=x;
return true;
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
for(int i=1;i<=n;i++) G[i].clear(),a[i]=0;
for(int i=1;i<n;i++) {
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
if(dfs(1,0)) puts("YES");
else puts("NO");
}
return 0;
}