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;
}

相关文章:

  • 2021-08-19
  • 2021-10-12
  • 2021-10-05
  • 2021-06-02
  • 2021-07-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-07
猜你喜欢
  • 2021-07-25
  • 2021-12-14
  • 2021-08-18
  • 2022-12-23
  • 2022-12-23
  • 2021-12-09
  • 2021-10-17
相关资源
相似解决方案