• 杭电多校6 F - Maex (树形DP)


     input:

    3
    5
    1 2
    3 2
    1 5
    4 1
    3
    1 2
    2 3
    1

    output:

    8
    6
    1
    

    题目大意:给我们一棵树,让我们给树上的每个结点设计一个权值,对于每个结点i有这样一个定义:b[i]是以i为根节点的子树中最小的没有出现过的非负整数,让我们求出所有结点b数组的值之和最大是多少。

    解题思路:因为b数组是对应子树中没有出现过的最小的非负整数,而最小的非负整数是0,所以为了让b数组的值尽可能大,一棵子树中应该尽可能包含0,1,2,3……这种按顺序从大到小的数字,并且数字越小就越应该放在更底层的子树中,这样就保证了从底层往上,结点对应b数组的值就越来越大,而我们可以发现b数组的值恰好就是以该点为根的子树中结点的数目,所以我们的思路就是在树中找一条链,使得分别以这条链上每一个结点为根的子树大小之和最大,所以我们可以先dfs预处理出以该点为根的子树中包含的结点数目,然后再进行第二遍dfs得到一条链上所能获得的最大权值之和。

    上代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace std;
    7. const int N=5e5+10;
    8. int a[N],n,h[N],e[N<<1],ne[N<<1],idx,depth[N];
    9. void add(int u,int v)
    10. {
    11. e[idx]=v;
    12. ne[idx]=h[u];
    13. h[u]=idx++;
    14. }
    15. long long dp[N],du[N],ans=-0x3f3f3f3f,maxv[N];
    16. void dfs(int u,int fa)
    17. {
    18. dp[u]=1;
    19. for(int i=h[u];i!=-1;i=ne[i])
    20. {
    21. int j=e[i];
    22. if(j==fa)
    23. continue;
    24. dfs(j,u);
    25. dp[u]+=dp[j];
    26. }
    27. }
    28. void dfs_u(int u,int fa)
    29. {
    30. if(fa==-1)
    31. maxv[u]=dp[u];
    32. else
    33. maxv[u]=dp[u]+maxv[fa];
    34. if(du[u]==1)
    35. {
    36. ans=max(ans,maxv[u]);
    37. }
    38. for(int i=h[u];i!=-1;i=ne[i])
    39. {
    40. int j=e[i];
    41. if(j==fa)
    42. continue;
    43. dfs_u(j,u);
    44. }
    45. }
    46. int main()
    47. {
    48. ios::sync_with_stdio(false);
    49. cin.tie(0);
    50. cout.tie(0);
    51. int t;
    52. cin>>t;
    53. while(t--)
    54. {
    55. cin>>n;
    56. if(n==1)
    57. {
    58. cout<<1<
    59. continue;
    60. }
    61. memset(h,-1,sizeof h);
    62. memset(du,0,sizeof du);
    63. memset(maxv,0,sizeof maxv);
    64. memset(dp,0,sizeof dp);
    65. idx=0;
    66. ans=-0x3f3f3f3f;
    67. for(int i=1;i
    68. {
    69. int u,v;
    70. cin>>u>>v;
    71. add(u,v);
    72. du[v]++;
    73. add(v,u);
    74. du[u]++;
    75. }
    76. dfs(1,-1);
    77. dfs_u(1,-1);
    78. cout<
    79. }
    80. return 0;
    81. }

  • 相关阅读:
    Javascript实现继承的几种方式
    Mysql存储json格式数据
    CSAPP 练习题 2.25
    SolidWorks弯曲的波纹管制作教程
    Leetcode刷题449. 序列化和反序列化二叉搜索树
    C++ 学习(三)运算符 - 算术运算符、赋值运算符、比较运算符、逻辑运算符
    vscode git 拉取报错 在签出前,请清理存储库工作树
    PyQt5快速开发与实战 4.2 QWidget
    74 QML ProgressBar显示进度数字
    计算机与软件技术系毕业设计(论文)实施意见-计算机毕业设计论文怎么写
  • 原文地址:https://blog.csdn.net/weixin_54562114/article/details/126179256