codeforces 1436D - Bandit in a City (貪心)
阿新 • • 發佈:2020-10-25
題目連結:https://codeforces.com/problemset/problem/1436/D
對於每個子樹,最好的情況是所有的人都平均分配到每個葉子上,
但有些人是不能往回走的,不過這並不影響答案,因為如果有人過不來,那答案必定比當前節點的 \(sum[u]/lev[u]\) 大
所以只需要從葉子到根節點統計\(sum[u]/lev[u]\)的最大值即可
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> #include<stack> #include<queue> using namespace std; typedef long long ll; const int maxn = 200100; int n; ll ans; ll a[maxn]; int h[maxn],cnt = 0; struct E{ int to,next; }e[maxn*2]; void add(int u,int v){ e[++cnt].to = v; e[cnt].next = h[u]; h[u] = cnt; } ll lev[maxn]; ll sum[maxn]; void dfs(int u,int par){ sum[u] = a[u]; lev[u] = 0; int cnt = 0; for(int i=h[u];i!=-1;i=e[i].next){ int v = e[i].to; if(v == par) continue; ++cnt; dfs(v,u); lev[u] += lev[v]; sum[u] += sum[v]; } if(!cnt) lev[u] = 1ll; ll tmp; if(sum[u] % (1ll * lev[u]) == 0) tmp = (sum[u] / (1ll * lev[u])) ; else tmp = (sum[u] / (1ll * lev[u]) + 1); ans = max(ans,tmp); } ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; } int main(){ memset(h,-1,sizeof(h)); n = read(); int u; ans = 0; for(int i=2;i<=n;++i){ u = read(); add(u,i), add(i,u); } for(int i=1;i<=n;++i) a[i] = read(); dfs(1,0); printf("%lld\n",ans); return 0; }