codeforces 660 div2 C

题意: 给你一个图(树),让你判断每个城市的的幸福值是否正确。
幸福值计算为 h = good - bad 开心的减去不开心的。
好心情的人可以变坏,但是坏心情的人就不能变好,在城市内不能变化。

对于每一个城市,我们可以知道:
happy_man + bad_man = total_number(总经过的人)
happy_man - bad_man = h(幸福值)
化简得 happy_man = (total_number + h) / 2, bad_man = (total_number-happy_man)
所以有一个判断条件 ,total_number+h 是偶数,且happy_man和bad_man的数量都应该大于0,。由于我们之后用dfs递归,所以只允许好人的数量增加(反着来的),所以 happy_man > last_happy_man.这里用以为数组去存happy_man比较好计算和实现。

用dfs去处理每个分支。可以精准算出经过改城市的人数。和处理每一个结点。

c++代码:

#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 1e9+7;
const int N = 200010;

int p[N],hh[N],hp[N];
int e[N],ne[N],h[N],idx=1;
bool book[N],plas;

void add(int a,int b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

int dfs(int u){
	if(!plas) return 0;
	int up = 0,pp = 0,last_hp = 0;
	for(int i=h[u];i;i=ne[i]){
		int j = e[i];
		if(book[j]) continue;
		book[j] = true;
		pp += dfs(j);
		last_hp += hp[j];
	}
	pp += p[u];
	hp[u] = (pp+hh[u])/2;
	up = pp-hp[u];
	if((pp+hh[u])%2 || hp[u]<0 || up < 0 || hp[u] < last_hp) plas = false;
	return pp;
}

void init(){
	memset(book,false,sizeof(book));
	idx = 1; plas = true;
	memset(h,0,sizeof(h));
}

signed main(){
	IOS;
	#ifdef ddgo
		freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
	#endif
	
	int tt; cin>>tt;
	while(tt --){
		init();
		int n,m; cin>>n>>m;
		for(int i=1;i<=n;i++) cin>>p[i];
		for(int i=1;i<=n;i++) cin>>hh[i];
		n -= 1;
		while(n --){
			int x,y; cin>>x>>y;
			add(x,y);
			add(y,x);
		}
		book[1] = true;
		dfs(1);
		cout<<(plas?"YES":"NO")<<endl;
	}
	
    return 0;
}

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页