树形dp1

alt alt

package com.zhang.reflection.面试.算法模版.动态规划;
import java.util.Scanner;
/**
 * 小红拿到了一棵有根树。根节点为1号节点。
 * 所谓树,指没有回路的无向连通图。
 * 现在小红想给一部分点染成红色。之后她有 q\q 次询问,每次询问某点的子树红色节点的个数。
 *
 * 第一行一个正整数 nn ,代表树的节点个数。
 * 第二行有 n-1n−1 个正整数,分别表示第 22 个节点到第 nn 个节点每个节点的父亲。
 * 接下来一个长度为 nn 的、由'W'或'R'字符组成的字符串。第 ii 个字符为'W'代表该字符没被染色,若字符为'R'代表该字符被染成了红色。
 * 接下来一个正整数 qq ,代表小红的询问次数。
 * 接下来的 qq 行,每行有一个正整数 xx ,代表一次询问。
 * (1<= n,q <= 10^5,1 <= x <= n)(1≤n,q≤10
 * 5
 *  ,1≤x≤n)
 */
public class 树形dp {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        // 用一个数组存每个节点的父亲节点
        int[] tree = new int[n+1];
        // 存总节点数
        tree[0] = n;
        // 根节点
        tree[1] = -1;
        // 构建树
        for (int i = 2; i <= n; i++) {
            tree[i] = sc.nextInt();
        }

        // 读取节点颜色标记
        char[] arr = sc.next().toCharArray();

        // dp[i]表示节点i的子树的红色节点个数
        int[] dp = new int[n+1];

        // 先记录所有的红色节点
        for (int i = 1; i <= n; i++) {
            if (arr[i-1] == 'R') {
                dp[i] = 1;
            }
        }
        // 再自底向上将子树的有色节点个数累加给父亲节点
        for (int i = n; i > 1; i--) {
            dp[tree[i]] += dp[i];
        }

        // 读取查询次数
        int q = sc.nextInt();
        while(q-- > 0) {
            int x = sc.nextInt();
            System.out.println(dp[x]);
        }
    }
}

全部评论

相关推荐

点赞 评论 收藏
分享
牛客965593684号:假的,字节hr都是不会找你内推的,直接就是同学我们约个面试?他们有权限直接捞你的。
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务