1. 程式人生 > 實用技巧 >Codeforces Round #660 (Div. 2) C. Uncle Bogdan and Country Happiness

Codeforces Round #660 (Div. 2) C. Uncle Bogdan and Country Happiness

題目連結:https://codeforc.es/contest/1388/problem/C

題意:給一棵根為1的樹 m個人,開始都在根節點,每晚這些人都要回到自己的住處,回去的路上隨時可以心情變壞

但是變壞了就不能變好 為是否存在一種情況 滿足所有點 h[i]成立 h[i]=心情好的人數-心情壞的人數

每個人開始的心情是可以自己設定的,這點要讀出來

思路:首先考慮的是假設條件然後判斷是否成立,在樹上,如果是從上而下的check的話 連通過當前點的總人數都無法確定

所以考慮從底往上來check 假設zong 為通過該點的總人數 列方程可知 good-bad=h good+bad=zong 可知2*good=(zong+h)

所以zong+h 必須為偶數才能滿足條件 還有就是good不能大於zong abs(h)也不能大於總 還有題目的條件good[u]<good[v]

當時寫錯的原因是 判斷good[u]<good[v]的時候 應該判斷的是所有子節點的總good[v] 而自己只是一個一個的判斷 沒有將子節點的累加起來

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const
int maxn=1e5+10; 7 const int mod=1e9+7; 8 9 int n,m; 10 int p[maxn]; 11 int h[maxn]; 12 vector<int>E[maxn]; 13 int good[maxn]; 14 int zong[maxn]; 15 16 int f; 17 void init() 18 { 19 f=0; 20 for(int i=0;i<=n;i++) 21 { 22 E[i].clear(); 23 zong[i]=0; 24 good[i]=0
; 25 } 26 } 27 void dfs(int u,int fa) 28 { 29 int sum=0; 30 for(auto &v:E[u]) 31 { 32 if(v==fa) 33 continue; 34 dfs(v,u); 35 zong[u]+=zong[v]; 36 sum+=good[v]; 37 } 38 zong[u]+=p[u]; 39 int k=zong[u]+h[u]; 40 if(k%2||abs(h[u])>zong[u]) f=1; 41 good[u]=(h[u]+zong[u])/2; 42 if(good[u]<sum) 43 f=1; 44 } 45 46 47 48 int main() 49 { 50 ios::sync_with_stdio(false); 51 cin.tie(0); 52 int t; 53 cin>>t; 54 while(t--) 55 { 56 cin>>n>>m; 57 init(); 58 for(int i=1;i<=n;i++) 59 { 60 cin>>p[i]; 61 } 62 for(int i=1;i<=n;i++) 63 { 64 cin>>h[i]; 65 } 66 for(int i=1;i<n;i++) 67 { 68 int x,y; 69 cin>>x>>y; 70 E[x].pb(y); 71 E[y].pb(x); 72 } 73 dfs(1,0); 74 if(f) 75 cout<<"NO"<<'\n'; 76 else 77 cout<<"YES"<<'\n'; 78 79 } 80 81 82 83 84 85 86 87 88 89 90 }
View Code