codeforces 1436D - Bandit in a City (贪心)
题目链接: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;
}