携程8.30笔试第三题【DFS】

题目:树的每个节点被染为rgb三色,求删掉一条边,满足分成两个连通块都恰好包含三种颜色的边的数量。
思路:统计子树中含有的rgb的数量,判断是否包含三种颜色,然后再用总的rgb数减去子树中的rgb数量,判断是否包含三种颜色。
public class Xiecheng830Q3 {
        static int n, r, g, b;
        static char[] colors;
        static List<List<Integer>> nxs = new ArrayList<>();
        static int res = 0;

        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            n = sc.nextInt();
            sc.nextLine();
            colors = sc.nextLine().toCharArray();
            // 统计rgb的数量
            for(char c : colors) {
                if(c == 'r') r++;
                else if(c == 'g') g++;
                else b++;
            }
            // 初始化并构造无向图
            for(int i = 0; i < n; i++) nxs.add(new LinkedList<>());
            for(int i = 0; i < n - 1; i++) {
                int a = sc.nextInt() - 1;   //题目中给的下标是1开始
                int b = sc.nextInt() - 1;
                nxs.get(a).add(b);
                nxs.get(b).add(a);
            }
            // 起点随便选,-1表示不存在的节点
            dfs(1, -1);
            System.out.println(res);
        }

        static int[] dfs(int node, int pre) {
            int[] color = new int[3];
            if(colors[node] == 'r') color[0]++;
            else if(colors[node] == 'g') color[1]++;
            else color[2]++;

            //如果是叶子节点,就直接返回
            if(nxs.get(node).size() == 1 && nxs.get(node).get(0) == pre) return color;

            // 遍历相邻节点,把子树返回来的数量加到color里
            for(int nx : nxs.get(node)) {
                // nx != pre的条件是防止无向图往回走
                if(nx != pre) add(color, dfs(nx, node));
            }

            // 判断是否符合题目条件
            if(color[0] > 0 && color[1] > 0 && color[2] > 0 && r - color[0] > 0 && g - color[1] > 0 && b - color[2] > 0)  res++;
            return color;
        }

        // 数组相加
        static void add(int[] a, int[] b) {
            for(int i = 0; i < 3; i++) a[i] += b[i];
        }
}
样例:
7
rgbrgbg
1 2
2 3
3 4
4 5
5 6
6 7

1


#携程笔试#
全部评论
问一个很低级的问题,dfs里面删除一个边的操作怎么体现?
点赞 回复 分享
发布于 2022-08-31 23:36 上海
太秀了,怎么想到的
点赞 回复 分享
发布于 2022-08-31 18:45 湖北
这个更像bfs
点赞 回复 分享
发布于 2022-09-02 21:03 浙江
请问有没有可能,断了以后,成为3段子树而不是2段?
点赞 回复 分享
发布于 2022-08-31 22:06 江苏
请问又python代码吗
点赞 回复 分享
发布于 2022-08-31 12:02 四川

相关推荐

02-15 14:18
已编辑
江西工程学院 Java
点赞 评论 收藏
分享
关于“实习生工资多少才算正常”,其实并没有一个放之四海而皆准的标准,但如果结合一线城市的生活成本、工作强度以及实习本身创造的价值来看,我个人认为6000&nbsp;元左右应当是一个基本及格线,也就是每天&nbsp;200&nbsp;多元。如果能达到&nbsp;300、400&nbsp;元一天,甚至更高,那无疑是更理想的状态。首先,从现实成本看,房租、通勤、餐饮几乎都是刚性支出。低于这个水平的实习,往往意味着实习生需要用家庭或存款“倒贴”工作,这在长期来看并不合理。实习本质上是学习,但并不等于“廉价劳动力”,更不应该是经济压力的来源。其次,愿意给实习生更高薪资的公司,通常不会是差公司。这至少说明两点:一是公司资金相对充足,不是靠压缩人力成本勉强维持;二是公司认可实习生的价值,希望你真正参与业务、创造产出,而不是只做边角料工作。很多高薪实习往往伴随着更规范的培养体系、更高的信息密度和更真实的项目经验。当然,高工资并不等于一切,但它往往是一个重要信号。能给到&nbsp;300、400&nbsp;元一天甚至更多的公司,往往对效率、能力和长期发展更有追求,也更可能处在一个有前景的赛道中。总结来说,实习工资不仅是钱的问题,更是公司态度、实力和发展前景的体现。在条件允许的情况下,争取一份“付得起你时间”的实习,本身就是一种理性选择。
北国牛马:你是不是忘了你一周只能上五天班,月薪6000那你日薪就得300了,日薪200一个月也就4000,也就刚好覆盖生活成本了
实习生工资多少才算正常?
点赞 评论 收藏
分享
评论
4
9
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务