C. Uncle Bogdan and Country Happiness(DFS)

C. Uncle Bogdan and Country Happiness(DFS)

思路: d f s dfs dfs

设经过城市 i i i的好人为: g [ i ] g[i] g[i],拜访城市 i i i的总人数为: a [ i ] a[i] a[i]
主要是找到 g [ i ] g[i] g[i]的表达式,这题就解决了。
根据: g [ i ] − ( a [ i ] − g [ i ] ) = h [ i ] → g [ i ] = a [ i ] + h [ i ] 2 g[i]-(a[i]-g[i])=h[i]\rightarrow g[i]=\dfrac{a[i]+h[i]}{2} g[i](a[i]g[i])=h[i]g[i]=2a[i]+h[i]

找到三个限制条件:

1: 2 2 2能整除 a [ i ] + h [ i ] a[i]+h[i] a[i]+h[i]

2: g [ i ] ∈ [ 0 , a [ i ] ] g[i]\in[0,a[i]] g[i][0,a[i]]

3: g [ i ] ≥ ∑ v ∈ s o n g [ v ] g[i]\geq \sum\limits_{v\in{son}} g[v] g[i]vsong[v]

然后跑 d f s dfs dfs

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define reg register
#define pb push_back
#define over {ok=0;return;}
int n,t,m,h[N],p[N],a[N],g[N];
bool ok;
vector<int>e[N];
void dfs(int u,int fa){
	a[u]=p[u];int sum=0;
	for(auto v:e[u]){
		if(v==fa) continue;
		dfs(v,u);
		sum+=g[v];a[u]+=a[v];
	}
	if((a[u]+h[u])&1) over;
	g[u]=(a[u]+h[u])>>1;
	if(!(g[u]>=0&&g[u]<=a[u])) over;
	if(sum>g[u]) over;  
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);ok=1;
		for(reg int i=1;i<=n;i++) scanf("%d",&p[i]);
		for(reg int i=1;i<=n;i++) scanf("%d",&h[i]);
		for(int i=1,u,v;i<n;i++)
			scanf("%d%d",&u,&v),e[u].pb(v),e[v].pb(u);
		dfs(1,0);
		puts(ok?"YES":"NO");for(int i=1;i<=n;i++) e[i].clear();
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷酷的Herio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值