• Codeforces Round #790 (Div. 4) G. White-Black Balanced Subtrees 感觉很好的树形dp的板子题


    翻译:

    您得到一个有根的树,其中包含从1到𝑛编号为𝑛的顶点。根结点是顶点1。还有一个字符串𝑠表示每个顶点的颜色:如果𝑠𝑖=𝙱,那么顶点𝑖是黑色的,如果𝑠𝑖=𝚆,那么顶点𝑖是白色的。

    如果白色顶点的数量等于黑色顶点的数量,则该树的子树称为平衡的。计算平衡子树的数量。

    树是没有循环的连通无向图。有根树是一棵有选定顶点的树,称为根。在这个问题中,所有树的根都是1。

    该树由包含𝑛−1数字的父数组𝑎2,…,𝑎𝑛指定:对于所有𝑖=2,…,𝑛,𝑎𝑖是顶点的父数组,其数字为𝑖。顶点𝑢的父顶点是从𝑢到根节点的简单路径上的下一个顶点。

    顶点𝑢的子树是所有通过𝑢到达根的简单路径的顶点集合。例如,在下图中,7在3的子树中,因为简单路径7→5→3→1经过3。注意,顶点包含在它的子树中,而根的子树就是整个树。

    这张照片显示的树𝑛= 7,𝑎=[1,1,2,3,3,5],和𝑠=𝚆𝙱𝙱𝚆𝚆𝙱𝚆。顶点3处的子树是平衡的。
    输入
    第一行输入包含一个整数𝑡(1≤𝑡≤104)——测试用例的数量。

    每个测试用例的第一行包含一个整数𝑛(2≤𝑛≤4000)——树中的顶点数量。

    每个测试用例的第二行包含𝑛−1整数𝑎2,…,𝑎𝑛(1≤𝑎𝑖<𝑖)-顶点2,…,𝑛的父结点。

    每个测试用例的第三行包含一个长度为𝑛的字符串𝑠,由字符𝙱和𝚆组成——这是树的颜色。

    保证所有测试用例的𝑛值的总和不超过2⋅105。

    输出
    对于每个测试用例,输出一个整数——平衡子树的数量。

    例子
    inputCopy
    3.
    7
    1 1 2 3 3 5
    WBBWWBW
    2
    1
    BW
    8
    1 2 3 4 5 6 7
    BWBWBWBW
    outputCopy
    2
    1
    4
    请注意
    第一个测试用例如图所示。只有顶点2和3处的子树是平衡的。

    在第二个测试用例中,只有顶点1的子树是平衡的。

    在第三个测试用例中,只有顶点1、3、5和7处的子树是平衡的。

    思路:

    典型的树形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. using namespace::std;
    15. typedef long long ll;
    16. int n,t;
    17. inline __int128 read(){
    18. __int128 x = 0, f = 1;
    19. char ch = getchar();
    20. while(ch < '0' || ch > '9'){
    21. if(ch == '-')
    22. f = -1;
    23. ch = getchar();
    24. }
    25. while(ch >= '0' && ch <= '9'){
    26. x = x * 10 + ch - '0';
    27. ch = getchar();
    28. }
    29. return x * f;
    30. }
    31. inline void print(__int128 x){
    32. if(x < 0){
    33. putchar('-');
    34. x = -x;
    35. }
    36. if(x > 9)
    37. print(x / 10);
    38. putchar(x % 10 + '0');
    39. }
    40. vector<int>q[4005];
    41. string s;
    42. int an=0,bn=0,cn=0;
    43. ll dp[4005];
    44. void dfs(int x,int fa){
    45. for (int i =0; isize(); i++) {
    46. dfs(q[x][i],x);
    47. }
    48. if (s[x]=='W') {
    49. dp[x]+=1;
    50. }
    51. else{
    52. dp[x]+=-1;
    53. }
    54. dp[fa]+=dp[x];
    55. }
    56. int we;
    57. void solv(){
    58. memset(dp, 0, sizeof dp);
    59. cin>>n;
    60. for (int i =0; i<=n; i++) {
    61. q[i].clear();
    62. }
    63. for (int i =2; i<=n; i++) {
    64. cin>>we;
    65. q[we].push_back(i);
    66. }
    67. cin>>s;
    68. s=' '+s;
    69. dfs(1,0);
    70. int na=0;
    71. // for (int i=1; i<=n; i++) {
    72. // printf("%lld ",dp[i]);
    73. // }
    74. // printf("\n");
    75. for (int i =1; i<=n; i++) {
    76. if (dp[i]==0) {
    77. na++;
    78. }
    79. }
    80. printf("%d\n",na);
    81. }
    82. int main(){
    83. ios::sync_with_stdio(false);
    84. cin.tie(); cout.tie();
    85. cin>>t;
    86. while (t--) {
    87. solv();
    88. }
    89. return 0;
    90. }
    91.  

  • 相关阅读:
    CASIO程序(线路计算6.0版)
    qt 多语言版本 QLinguist使用方法
    二叉树的层序遍历
    【2023年11月第四版教材】软考高项极限冲刺篇笔记(3)
    SRRC认证的必要性:保障电子产品质量安全的重要措施
    Java泛型知识总结
    使用ensp搭建路由拓扑,并使用ospf协议实现网络互通实操
    【云原生之k8s】Yaml文件详解
    什么是观察者模式?用 Python 如何实现 Observer(观察者或发布订阅)对象行为型模式?
    opensql
  • 原文地址:https://blog.csdn.net/weixin_63555280/article/details/128105760