原题连接
想法是从叶子节点出发往跟上走,然后在用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;elsecout<<"NO"<<endl;}return 0;
}