LeetCode 2477-到达首都的最少油耗

文章介绍了如何使用贪心策略和深度优先搜索算法解决一个关于节点间人员移动的问题,通过计算每个节点子树中的人数及其向下移动所需的最少车辆数,得出整体最小汽油开销。代码展示了如何遍历子节点并计算到达每个节点的代价。
摘要由CSDN通过智能技术生成

在这里插入图片描述

方法一:贪心 + 深度优先搜索

思路与算法:题目等价于给出了一颗以节点 0 0 0 为根节点的树,并且初始树上的每一个节点上都有一个人,现在所有人都需要通过「车子」向结点 0 0 0 移动。

对于某一个节点 x x x x ≠ 0 x \neq 0 x=0,其父节点为 y y y。因为以节点 x x x 为根结点的子树上的人都需要通过边 x → y x \rightarrow y xy 向节点 0 0 0 移动,所以为了使这条边上的「车子」利用率最高,我们贪心的让 x x x 的全部子节点上的人到了节点 x x x 后再一起坐车向上移动,我们不妨设以节点 x x x 为根节点的子树大小为 cnt x \text{cnt}_x cntx,那么我们至少需要「车子」的数量为 ⌈ cnt x seats ⌉ \lceil \frac{\textit{cnt}_x}{\textit{seats}} \rceil seatscntx,其中 seats \textit{seats} seats 为一辆车的给定座位数。

那么我们可以通过从根结点 0 0 0 往下进行「深度优先搜索」,每一条边上「车子」的数目即为该条边上汽油的开销,统计全部边上汽油的开销即为最终答案。

代码

class Solution {
    long res = 0;
    public long minimumFuelCost(int[][] roads, int seats) {
        int n = roads.length;
        List<Integer>[] graph = new List[n + 1];
        for(int i = 0; i <= n; i++){
            graph[i] = new ArrayList<Integer>();
        }
        for(int[] edge : roads){                                       //构造图
            graph[edge[0]].add(edge[1]);
            graph[edge[1]].add(edge[0]);
        }
        dfs(0, -1, seats, graph);                                      //从节点0开始
        return res;
    }

    public int dfs(int cur, int father, int seats, List<Integer>[] graph){
        int peopleSum = 1;
        for(int child : graph[cur]){
            if(child != father){                                       //排除父节点
                int peopleCnt = dfs(child, cur, seats, graph);
                peopleSum += peopleCnt;
                res += (peopleCnt + seats - 1) / seats;                //到达每个节点所需代价
            }
        }
        return peopleSum;
    }
}

值得学习的点

  • 只遍历子节点的做法 if(child != father){...}
  • 计算到达每个节点需要的代价 res += (peopleCnt + seats - 1) / seats,向上取整的做法十分巧妙。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值