• D. Bandit in a City(DFS + 叶子节点数目)


    Problem - 1436D - Codeforces

     

    输出标准输出
    城市里出现了强盗! 他们中的一个正试图尽可能多地抓捕市民。

    这个城市由n个广场组成,由n-1条道路连接,从任何其他广场都可以到达任何广场。1号广场是主广场。

    星期天散步后,所有的道路都改为单行道,这样就有可能从主广场到达任何一个广场。

    当强盗出现在主广场的时候,第i个广场上有ai个公民。现在,以下过程将开始。首先,每个目前在有一些出城单行道的广场上的公民选择其中一条道路,并沿着它移动到另一个广场。然后,强盗选择一条从他所在的广场发出的单行道,并沿着它移动。这个过程重复进行,直到强盗位于一个没有出城道路的广场。匪徒抓住了该广场上的所有公民。

    匪徒想抓尽可能多的市民;市民则想尽量减少被抓的人数。匪徒和公民在任何时候都知道所有公民的位置,公民可以合作。如果双方都采取最佳行动,将有多少公民被抓?

    输入
    第一行包含一个整数n--城市中的方块数(2≤n≤2⋅105)。

    第二行包含n-1个整数p2,p3...pn,意味着从广场pi到广场i有一条单行道(1≤pi

    第三行包含n个整数a1,a2,...,an--最初每个广场上的公民数量(0≤ai≤109)。

    输出
    打印一个整数--如果双方都采取最佳行动,强盗将捕获的公民数量。

    例子
    输入
    3
    1 1
    3 1 2
    输出
    3
    输入
    3
    1 1
    3 1 3
    输出
    4
    注意
    在第一个例子中,1号方格的公民可以分成2+1两组,因此2号和3号方格将各有3名公民。

    在第二个例子中,无论公民如何行动,强盗至少可以抓到4个公民。

    题解:
    根据题意我们可以发现,强盗只能从一棵子树的根部,不断往下遍历,不可往回走,同样,公民也无法往回走,但是公民可以向他所在的子树分配公民,使强盗抓到的人最少,要想抓到的人最少,肯定会不断平均往下分配公民,导致最终的结果就是,一个子树的sum[i]/子树叶子节点数量son[i]

    分配公民时存在两种情况

    1.如果存在一个儿子v,使得就算不给v分配一个居民,最后还是v子树内的叶子节点居民最大,那么就把问题规模缩小成以v为根的子树了(其他儿子就没用了)

    2.如果不存在这种儿子v ,就存在一种分配方式使得所有叶子节点尽量平均

    最终所有的情况一最后都变成了情况二

    由于强盗也同样聪明,最后肯定会找遍历途中最大的

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<map>
    4. #include<queue>
    5. #include<vector>
    6. #include<cstring>
    7. #include<stack>
    8. using namespace std;
    9. long long s[200050];
    10. long long son[200050];
    11. long long a[200050];
    12. vector<int> p[200050];
    13. void dfs(int u)
    14. {
    15. int f = 0;
    16. s[u] = a[u];
    17. for(int i = 0;i < p[u].size();i++)
    18. {
    19. int j = p[u][i];
    20. dfs(j);
    21. f = 1;
    22. son[u] += son[j];
    23. s[u] += s[j];
    24. }
    25. if(!f)
    26. son[u] = 1;
    27. }
    28. void solve()
    29. {
    30. int n;
    31. cin >> n;
    32. for(int i = 2;i <= n;i++)
    33. {
    34. int x;
    35. cin >> x;
    36. p[x].push_back(i);
    37. }
    38. for(int i = 1;i <= n;i++)
    39. {
    40. cin >> a[i];
    41. }
    42. dfs(1);
    43. long long ans = 0;
    44. for(int i = 1;i <= n;i++)
    45. {
    46. ans = max(ans,s[i]/son[i]+(s[i]%son[i]!=0));
    47. }
    48. cout<<ans;
    49. }
    50. int main()
    51. {
    52. int t = 1;
    53. // cin >> t;
    54. while(t--)
    55. {
    56. solve();
    57. }
    58. }
    59. //
    60. //abcdef
    61. //babcdef
    62. //1110011
    63. //


     

  • 相关阅读:
    HTML5期末考核大作业,网站——旅游景点。 学生旅行 游玩 主题住宿网页
    洛谷 模拟 普及-
    软件外包开发代码质量评测
    如何用PHP获取各大电商平台的数据
    百度地图——地图找房功能
    Selector的使用
    App上架Apple App Store和Google Play流程
    毕业设计 stm32单片机的家庭成员监控监护系统 - 物联网 嵌入式
    js数据结构算法[栈操作]
    【毕业设计】基于单片机的智能温控农业大棚系统 - 物联网 stm32
  • 原文地址:https://blog.csdn.net/m0_64158084/article/details/127910224