CF1388C Uncle Bogdan and Country Happiness (dfs)
Practice link: https://codeforces.ml/problemset/problem/1388/C
题意: 由 m 个人每个人居住在某一个城市,每个人一开始都在 1 号城市,每个人有不同的心情,1表示好心情,0表示坏心情,每个人在回家途中可以由 1 变成 0 ,但不能由 0 变成 1,告诉你在某个城市经过这个城市的人的心情值总和sum[ i ],问你是否合法。
思路:首先,我们假设经过城市 i 拥有好辛勤的人为 good[ i ],拥有坏心情的人为 bad[ i ],设经过这个点的人数为 num[ i ],则good[ i ] + bad[ i ] = num[ i ],good[ i ] - bad[ i ] =sum[ i ],那么两式联立,得到 2*good[ i ] = num[ i ] + sum[ i ] ,因此得到条件一 : good[ i ] % 2 == 0 。再看条件,心情只能由 1 变成 0,不能由 0 变成 1,因此条件二:某一点的子树上的好心情的数量小于等于该点子树上的good[ i ]。还有一个就是:good [ i ]>=0 且 good[ i ]<=num[ i ]。
对于这些条件,我们可以通过dfs 去求得某一点上的这些值,去判断是否合法即可。
其中有一个求以某一个结点为根的所有子节点权值和的操作,记录一下
代码:
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define MOD 1e9+7 4 #define INF 0x3f3f3f3f 5 #define mem(a,x) memset(a,x,sizeof(a)) 6 #define _for(i,a,b) for(int i=a; i< b; i++) 7 #define _rep(i,a,b) for(int i=a; i<=b; i++) 8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 9 10 using namespace std; 11 const int MAXN = 100005; 12 int n,m; 13 int h[MAXN],p[MAXN],sum[MAXN],good[MAXN]; 14 vector<int>g[MAXN]; 15 int flag; 16 void dfs(int u,int fa) 17 { 18 if(flag==0)return; 19 sum[u]=p[u]; 20 int s=0; //good人数之和 21 for(int i=0;i<g[u].size();i++){ 22 int v=g[u][i]; 23 if(v==fa)continue; 24 dfs(v,u); 25 sum[u]+=sum[v]; 26 s+=good[v]; 27 } 28 int temp=sum[u]+h[u]; 29 if(temp%2!=0){flag=0;return;} 30 good[u]=temp/2; 31 if(good[u]>sum[u]||good[u]<0){flag=0;return;} 32 if(s>good[u]){flag=0;return;} 33 } 34 35 int main() 36 { 37 int T; 38 cin>>T; 39 while(T--){ 40 scanf("%d %d",&n,&m); 41 for(int i=1;i<=n;i++){ 42 scanf("%d",&p[i]); 43 g[i].clear(); 44 sum[i]=0; 45 good[i]=0; 46 } 47 for(int i=1;i<=n;i++){ 48 scanf("%d",&h[i]); 49 } 50 for(int i=1;i<n;i++){ 51 int a,b; 52 scanf("%d %d",&a,&b); 53 g[a].push_back(b); 54 g[b].push_back(a); 55 } 56 flag=1; 57 dfs(1,0); 58 if(flag)cout<<"YES"<<endl; 59 else cout<<"NO"<<endl; 60 } 61 return 0; 62 }
越自律,越自由