• K. Kingdom‘s Power,树形dp


    Problem - K - Codeforces

    time limit per test

    2.0 s

    memory limit per test

    512 megabytes

    input

    standard input

    output

    standard output

    Alex is a professional computer game player.

    These days, Alex is playing a war strategy game. The kingdoms in the world form a rooted tree. Alex's kingdom 1 is the root of the tree. With his great diplomacy and leadership, his kingdom becomes the greatest empire in the world. Now, it's time to conquer the world!

    Alex has almost infinite armies, and all of them are located at 1 initially. Every week, he can command one of his armies to move one step to an adjacent kingdom. If an army reaches a kingdom, that kingdom will be captured by Alex instantly.

    Alex would like to capture all the kingdoms as soon as possible. Can you help him?

    Input

    The first line of the input gives the number of test cases, T (1≤T≤105). T test cases follow.

    For each test case, the first line contains an integer n (1≤n≤106), where n is the number of kingdoms in the world.

    The next line contains (n−1)integers f2,f3,⋯,fn (1≤fi

    The sum of n in all test cases doesn't exceed 5×106.

    Output

    For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1), and y is the minimum time to conquer the world.

    Example

    input

    Copy

    2
    3
    1 1
    6
    1 2 3 4 4
    

    output

    Copy

    Case #1: 2
    Case #2: 6

    解析:

     题意:

    1号节点为根节点,根节点的军队数量是无线的,从根节点开始派兵,一次走一步,走遍所有的节点,需要多少步。

    性质:若一棵子树都多个子树,这先走深度小的子树再走深度深的子树,是最优的;同时还要考虑是从一棵子树返回来走向另一棵子树还是从根节点派兵走

    所以先dfs一次找出所有的节点的deep,再dfs找出最终答案;

    具体见代码:(这道树形dp感觉跟dp没什么关系)

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. using namespace std;
    16. typedef long long LL;
    17. const int N = 1e6 + 5;
    18. int n;
    19. vectorint, int>>G[N];
    20. int deep[N];
    21. LL ans;
    22. int d = 0, flg = 0;
    23. int dfs(int x,int fa) {
    24. deep[x] = deep[fa] + 1;
    25. if (G[x].size() == 0)return 1;
    26. for (int i = 0; i < G[x].size(); i++) {
    27. int j = G[x][i].second;
    28. int& v = G[x][i].first;
    29. v=dfs(j, x);
    30. }
    31. sort(G[x].begin(), G[x].end());
    32. return G[x].back().first + 1;
    33. }
    34. void dfs1(int x,int fa) {
    35. if (G[x].size() == 0) {
    36. if (flg == 0)ans += deep[x];
    37. else {
    38. ans += min(deep[x], d);
    39. }
    40. flg = 1;
    41. d = 0;
    42. return ;
    43. }
    44. for (int i = 0; i < G[x].size(); i++) {
    45. int j = G[x][i].second;
    46. d++;
    47. dfs1(j, x);
    48. d++;
    49. }
    50. }
    51. int main() {
    52. int T,cnt=0;
    53. scanf("%d", &T);
    54. while (T--) {
    55. cnt++;
    56. scanf("%d", &n);
    57. for (int i = 0; i <= n; i++)
    58. G[i].clear();
    59. for (int i = 2,a; i <= n; i++) {
    60. scanf("%d", &a);
    61. G[a].push_back({ 0,i });
    62. }
    63. deep[0] = -1;
    64. dfs(1,0);
    65. flg = 0, d = 0, ans = 0;
    66. dfs1(1,0);
    67. printf("Case #%d: %lld\n",cnt, ans);
    68. }
    69. return 0;
    70. }

  • 相关阅读:
    Qt5开发从入门到精通——第十二篇三节(Qt5 事件处理及实例——多线程应用、服务器端编程、客户端编程)
    赶紧进来修内功!!!带你认识C语言中各种进制数和原码反码补码.
    ONLYOFFICE 文档 7.5 现已发布:新增 PDF 编辑器、屏幕朗读器等功能
    节点异常检测 node-problem-detector
    uboot源码——根目录下的mkconfig文件分析
    操作系统运行环境
    Dockerfile 镜像创建
    Linux安全—iptables详解(概念和filter表)
    动手学深度学习—使用块的网络VGG(代码详解)
    FreeRTOS(以STM32F1系列为例子)
  • 原文地址:https://blog.csdn.net/Landing_on_Mars/article/details/133834167