C. Uncle Bogdan and Country Happiness
题意
有n个城市构成n-1条边的树 1号点为根
m个人每个人都在中心城市(根节点)工作
工作结束后回家 每个城市有live[i]个人居住
每个人都有mood值 1/-1当到达一个城市后他的mood值不变
但每个人可能再从某个城市到下一个城市的路中间改变他的mood值 1能变-1但是-1不能变1
现在每个城市都有happy值监测器 一个城市的happy值= 所有经过这个城市的人的mood值之和
现在给出每个城市happy预测值
问当所有人回到家后所有城市的happy值会不会出现预测值的情况
题解
我们发现一个城市i 的happy值最高不会超过以它为根的子树的城市中居住的人的总数sz[i]
最低也不会超过以它为根的子树的城市中居住的人的总数sz[i] 的相反值
同时一个城市i 的happy值-以它为根的子树的城市中居住的人的总数sz[i]应该是偶数
比如一个城市的happy值为7而sz[i]=10
假如10个人路过这里mood都为1那么 happy值为10
假如10个人中有一个mood为-1那么happy值为8
有两个mood为-1那么happy值为6
发现一个人mood由1变-1总的happy值-2 所以这个城市i的happy值 - sz[i]=偶数
因为有的人经过这个城市后mood由1变为-1 而有的人住在这个城市不会继续往后走
假设留在这个城市i的人mood都是-1那么 happy[i]>= sumhpson[i]-live[i]
假设留在这个城市i的人mood都是1那么 happy[i]>=sumhpson[i]+live[i]
sumhpson[i]表示城市i直接连接的子节点城市的happy值之和
所以显然一个城市i 的happy值应该比sumhpson[i]-live[i] 大
dfs统计sz并维护sumhpson
依靠这几个条件判断每个城市是否符合要求
还有另外一种判断方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #include <bits/stdc++.h> using namespace std; typedef long long ll; #define endl '\n' #define Turnoff std::ios::sync_with_stdio(false) const ll Max=1e5+5; int live[Max],hp[Max]; vector<int>mp[Max]; int sumhpson[Max],sz[Max];
void dfs_size(int now,int f){ for(auto i:mp[now]){ if(i==f)continue; sumhpson[now]+=hp[i]; dfs_size(i,now); sz[now]+=sz[i]; } return; } int main() { Turnoff; int t;cin>>t; while(t--){ int n,m;cin>>n>>m; for(int i=1;i<=n;i++)mp[i].clear(); for(int i=1;i<=n;i++){ cin>>live[i]; sz[i]=live[i]; sumhpson[i]=0; } for(int i=1;i<=n;i++){ cin>>hp[i]; } for(int i=1;i<n;i++){ int u,v;cin>>u>>v; mp[u].push_back(v); mp[v].push_back(u); } dfs_size(1,0);bool flag=0; for(int i=1;i<=n;i++){ if((hp[i]-sz[i])%2||hp[i]<-sz[i]||hp[i]>sz[i]||sumhpson[i]-live[i]>hp[i]){ flag=1; } } if(flag)cout<<"NO"<<endl; else cout<<"YES"<<endl; } }
|