codeforces1388C Uncle Bogdan and Country Happiness

https://codeforces.com/contest/1388/problem/C

以1为根,dfs整个树,设a[i]为这个点的快乐人,b[i]为网抑云,那么a[i]+b[i]=sum[i]整个子树的所有人,a[i]-b[i]=h[i],那么就判断a[i],b[i]有没有非负整数解就行了。另一个条件是人在路上可能会从快乐人变成网抑云,所以u的所以子树的a[v]之和要小于等于a[u]

#include
#define pb push_back
using namespace std;
typedef long long ll;

const int maxl=3e5+10;

int n,m,cas,k,cnt,tot,ans;
int p[maxl],a[maxl],b[maxl],h[maxl],sum[maxl];
int suma[maxl];
char s[maxl];
bool in[maxl]; 
vector e[maxl];

inline void dfs(int u,int fa)
{
	if(!ans) return;
	sum[u]=p[u];
	for(int v:e[u])
	{
		if(v==fa) continue;
		dfs(v,u);
		sum[u]+=sum[v];suma[u]+=a[v];
	}
	if((sum[u]+h[u])%2!=0)
		ans=0;
	a[u]=(sum[u]+h[u])/2;
	b[u]=sum[u]-a[u];
	if(suma[u]>a[u] || a[u]<0 || b[u]<0)
		ans=0;
}

inline void prework()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		e[i].clear();sum[i]=0;suma[i]=0;
		scanf("%d",&p[i]);
	}
	for(int i=1;i<=n;i++)
		scanf("%d",&h[i]);
	int u,v;
	for(int i=1;i<=n-1;i++)
	{
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	ans=1;
	dfs(1,0);
} 

inline void mainwork()
{
	
}

inline void print()
{
	if(ans)
		puts("YES");
	else
		puts("NO");	
}

int main()
{
	int t=1;
	scanf("%d",&t);
	for(cas=1;cas<=t;cas++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

你可能感兴趣的:(codeforces1388C Uncle Bogdan and Country Happiness)