题目大意:
给一个有N个结点的树,每个结点上都会有相应数量的工人居住,每天早上所有的工人都在根节点1,到了晚上,所有的工人都要一起回家,每个结点都有个快乐检查器,快乐值=快乐的人数-不快乐的人数,心情只能由快乐变为不快乐,再给N-1个快乐值h[i],问能否满足。解题思路:
先假设当前结点开心的人数为good,不开心的人数为bad,所以可得式子good+bad=总人数,good-bad=h[i],联立两式可得2*good=(总人数+h[i]),所以总人数+h[i]必须是偶数,同时good必须小于总人数,good[u]>good[v](v为u的子节点),因为结构为树,所以要把u的子节点的good相加在与u比较。代码:
// #include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#define pb emplace_back
#define LOCAL
using namespace std;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+5;
typedef long long ll;
typedef pair<int,int> Pii;
template <typename T>inline void read(T& t){
char c=getchar();t=0;
int f=1;
while(!isdigit(c)){
if(c=='-')f=-1;
c=getchar();
}
while(isdigit(c))t=t*10+c-48,c=getchar();
t=f*t;
}
template <typename T,typename... Args> inline void read(T& t,Args&... args){
read(t);read(args...);
}
int n,m;
bool flag;
int p[maxn],h[maxn];
vector<int> e[maxn];
void init(){
for(int i=1;i<=n;i++){
p[i]=0;
h[i]=0;
e[i].clear();
}
}
void dfs(int x,int fa){
int sum=0;
for(auto it:e[x]){
if(it==fa)continue;
dfs(it,x);
p[x]+=p[it];
sum+=h[it];
}
h[x]+=p[x];//总人数
if((h[x]%2)||(h[x]>2*p[x])||(h[x]<sum)){1.总人数必须为偶数,2.good人数必须小于总人数,3.good必须小于父节点
flag=false;
}
}
int main(){
int t;
read(t);
while(t--){
init();
flag=true;
read(n,m);
for(int i=1;i<=n;i++){
read(p[i]);
}
for(int i=1;i<=n;i++){
read(h[i]);
}
for(int i=1;i<n;i++){
int u,v;
read(u,v);
e[u].emplace_back(v);
e[v].emplace_back(u);
}
dfs(1,0);
puts(flag?"YES":"NO");
}
return 0;
}