题意: 有一个拥有n个城市的国家,这n个城市之间连通且只有n-1条边,这个国家有m个居民,他们都在1号城市上班,每天晚上m个居民都要通过最短路径回到自己家里,离开工作岗位的时候,可能有些人心情好,有些人心情不好,心情好的人可能路途中心情变得不好了,心情不好的人不会变好。每个城市有一个检测仪,它返回的值h[i]=num(好心情)-num(坏心情),现在告诉你每个城市的居民量和每个城市检测仪的返回值,问你给出来的这些返回值是否可能全部满足?
分析:n-1条边,很明显是一个树,通过树上dfs来判断每一个点是否合法,每个节点好心情人数为good[v]=(pp[v]+h[v])/2,其中pp[v]代表经过该点的总人数。
限制条件:
1、好心情人数为非负整数
2、父节点好心情人数不可能比其所有子节点好心情人数和更少(好心情人数只能变少,不可能变多)
3、好心情的人数不超过经过该点的总人数
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<queue>
//#define _for(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
double eps=1e-10;
ll mod=1e15+7;
const int INF =0x3f3f3f;
const int MAXN=2e3+10;
const int maxn = 1e5+10;
//ll inf=100000000000000;
//template<typename T>inline void read(T &x)
//{
// x=0;
// static int p;p=1;
// static char c;c=getchar();
// while(!isdigit(c)){if(c=='-')p=-1;c=getchar();}
// while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();}
// x*=p;
//}
typedef unsigned long long ull;
int p[100010],h[100010],pp[100010],good[100010];
vector<int> vec[100010];
int flag=0;
void dfs(int pre,int u){
int sum=0;
pp[u]=p[u];
for(int i=0;i<vec[u].size();i++){
int v=vec[u][i];
if(v==pre)continue;
dfs(u,v);
pp[u]+=pp[v];
sum+=good[v];
}
good[u]=(pp[u]+h[u])/2;
if(abs(pp[u]+h[u])%2==1||good[u]<0||pp[u]-good[u]<0||sum>good[u])
flag=1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)vec[i].clear(),good[i]=pp[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;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
vec[x].push_back(y);
vec[y].push_back(x);
}
flag=0;
dfs(1,1);
if(!flag){
printf("YES\n");
}
else {
printf("NO\n");
}
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
#include<queue>
//#define _for(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
double eps=1e-10;
ll mod=1e15+7;
const int INF =0x3f3f3f;
const int MAXN=2e3+10;
const int maxn = 1e5+10;
//ll inf=100000000000000;
//template<typename T>inline void read(T &x)
//{
// x=0;
// static int p;p=1;
// static char c;c=getchar();
// while(!isdigit(c)){if(c=='-')p=-1;c=getchar();}
// while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();}
// x*=p;
//}
typedef unsigned long long ull;
int p[100010],h[100010],pp[100010],good[100010];
vector<int> vec[100010];
int flag=0;
void dfs(int pre,int u){
int sum=0;
pp[u]=p[u];
for(int i=0;i<vec[u].size();i++){
int v=vec[u][i];
if(v==pre)continue;
dfs(u,v);
pp[u]+=pp[v];
sum+=good[v];
}
good[u]=(pp[u]+h[u])/2;
if(abs(pp[u]+h[u])%2==1||good[u]<0||pp[u]-good[u]<0||sum>good[u])
flag=1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)vec[i].clear(),good[i]=pp[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;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
vec[x].push_back(y);
vec[y].push_back(x);
}
flag=0;
dfs(1,1);
if(!flag){
printf("YES\n");
}
else {
printf("NO\n");
}
}
return 0;
}
return 0;
}