[CF1436D] Bandit in a City

Description

给定以 (1) 为根的 (n) 个结点的一棵树,每个结点上有 (a_i) 个人,每个人可以选择任意的子节点走,直到走到叶子结点为止,问最后人最多的叶子结点最少有多少人。

Solution

考虑一个递推关系,对于 (p) 的所有孩子 (q_i),首先 (p) 的答案一定不小于 (q_i) 的答案,也不小于子树权值和除以叶子结点总数,同时,(q_i) 中最大答案若不小于平均分配的结果,则这个最大答案一定可以被 (p) 取到

因此设 (f[p])(p) 的答案,(sum[p])(p) 的子树权值和,(cnt[p])(p) 子树中的叶子个数,则 (f[p]=max(q_1,...,q_k,sum[p]/cnt[p]))

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 1000005;

vector <int> g[N];
int n,t1,t2,t3,t4,a[N],f[N],s[N],c[N];

void dfs(int p)
{
    if(g[p].size()==0) c[p]=1;
    s[p]=a[p];
    for(int q:g[p])
    {
        dfs(q);
        c[p]+=c[q];
        s[p]+=s[q];
        f[p]=max(f[p],f[q]);
    }
    f[p]=max(f[p],(s[p]+c[p]-1)/c[p]);
}


signed main()
{
    cin>>n;
    for(int i=2;i<=n;i++) cin>>t1, g[t1].push_back(i);
    for(int i=1;i<=n;i++) cin>>a[i];
    dfs(1);
    cout<<f[1];
    return 0;
}
原文地址:https://www.cnblogs.com/mollnn/p/13893300.html