Leetcode 2477. 到达首都的最少油耗(建图 + DFS 一次遍历)

2023-12-05 15:44

本文主要是介绍Leetcode 2477. 到达首都的最少油耗(建图 + DFS 一次遍历),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • Leetcode 2477. 到达首都的最少油耗(建图 + DFS 一次遍历)
  • 题目
    • 给你一棵 n 个节点的树(一个无向、连通、无环图),每个节点表示一个城市,编号从 0 到 n - 1 ,且恰好有 n - 1 条路。0 是首都。给你一个二维整数数组 roads ,其中 roads[i] = [ai, bi] ,表示城市 ai 和 bi 之间有一条 双向路 。
    • 每个城市里有一个代表,他们都要去首都参加一个会议。
    • 每座城市里有一辆车。给你一个整数 seats 表示每辆车里面座位的数目。
    • 城市里的代表可以选择乘坐所在城市的车,或者乘坐其他城市的车。相邻城市之间一辆车的油耗是一升汽油。
    • 请你返回到达首都最少需要多少升汽油。
    • 1 <= n <= 10 ^ 5
    • roads.length == n - 1
    • roads[i].length == 2
    • 0 <= ai, bi < n
    • ai != bi
    • roads 表示一棵合法的树。
    • 1 <= seats <= 10 ^ 5
  • 解法
    • 建图 + DFS 一次遍历:
    • 第 1 步:
    • 思考不走回头路肯定是最优的,因此每个叶子节点均会发车
    • 第 2 步:
    • 如果车上座位比较多,则发车到父节点后,将所有人塞入最少的车
    • 第 3 步:
    • 实现仅在回溯时处理,
      • 叶子节点发一辆车,载一个人
      • 非叶子节点、将所有孩子节点的人加自己塞入最少的车
      • 根节点不能再发车了
    • 第 4 步:
    • 具体实现可以仅回溯人数 human,使用(human+seats-1)/seats 确定最少发了几辆车
    • 注意:发车到根节点即可,根节点不发车
    • 时间复杂度:O(n),空间复杂度:O(n+height)建树+递归栈深度
  • 代码
/*** 建图 + DFS 一次遍历:** 第 1 步:* 思考不走回头路肯定是最优的,因此每个叶子节点均会发车** 第 2 步:* 如果车上座位比较多,则发车到父节点后,将所有人塞入最少的车** 第 3 步:* 实现仅在回溯时处理,*     * 叶子节点发一辆车,载一个人*     * 非叶子节点、将所有孩子节点的人加自己塞入最少的车*     * 根节点不能再发车了** 第 4 步:* 具体实现可以仅回溯人数 human,使用(human+seats-1)/seats 确定最少发了几辆车* 注意:发车到根节点即可,根节点不发车* 时间复杂度:O(n),空间复杂度:O(n+height)建树+递归栈深度**/private long res;public long minimumFuelCost(int[][] roads, int seats) {this.res = 0L;int n = roads.length + 1;// 建树List<Integer>[] edgeList = buildTree(n, roads);// 递归遍历树dfsTraversalTree(0, -1, edgeList, seats);return this.res;}private List<Integer>[] buildTree(int n, int[][] edges) {List<Integer>[] edgeList = new ArrayList[n];for (int i = 0; i < n; i++) {edgeList[i] = new ArrayList<>();}for (int i = 0; i < edges.length; i++) {int u = edges[i][0];int v = edges[i][1];edgeList[u].add(v);edgeList[v].add(u);}return edgeList;}private int dfsTraversalTree(int son, int father, List<Integer>[] edgeList, int seats) {int human = 1;// 叶子节点if (edgeList[son].size() == 1 && edgeList[son].get(0).equals(father)) {// 到父节点发一辆车消耗一升油this.res++;return human;}for (int next : edgeList[son]) {if (next != father) {human += dfsTraversalTree(next, son, edgeList, seats);}}// 发车到根节点即可,根节点不发车if (son != 0) {// 到父节点多少辆车就是会消耗多少升油this.res += (human + seats - 1) / seats;}return human;}

这篇关于Leetcode 2477. 到达首都的最少油耗(建图 + DFS 一次遍历)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/458162

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

ural 1149. Sinus Dances dfs

1149. Sinus Dances Time limit: 1.0 second Memory limit: 64 MB Let  An = sin(1–sin(2+sin(3–sin(4+…sin( n))…) Let  Sn = (…( A 1+ n) A 2+ n–1) A 3+…+2) An+1 For given  N print  SN Input One