想法是从叶子节点出发往跟上走,然后在用bfs做。有些bug找不到了
dfs正好。
回溯的过程中统计总的人数,贪心的让每个节点的好心情的人数是正确的,然后进行条件判断,因为是从叶子节点走,所以本来的好人边坏变成了坏人变好
有这么一个数学方程式来推理好人的数目
node[i].good + node[i].sad = 总人数
node[i].good - node[i].sad = 题目的h[i]
然后两式子相加 可以推出来 node[i].good = (总人数 + 题目给的h[i]) / 2
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int p[N],h[N],s[N],good[N],fg;
vector<int>e[N];
void dfs(int fa,int u)
{
s[u]=p[u];
int sum=0;
for(int i = 0; i < e[u].size(); i++)
{
int v = e[u][i];
if(v!=fa)
{
dfs(u,v);
s[u]+=s[v];
sum+=good[v];
}
}
good[u]=(s[u]+h[u])/2;
if((s[u]+h[u])%2==1 || sum>good[u] || good[u]<0 || s[u]-good[u]<0 || s[u] + h [u] < 0)
fg=0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) e[i].clear(),good[i]=s[i]=0;
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,u,v;i<=n-1;i++)
{
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
fg=1;
dfs(1,1);
if(fg)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}