【数据结构和算法】到达首都的最少油耗

news2025/1/22 17:51:35

其他系列文章导航

Java基础合集
数据结构与算法合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

其他系列文章导航

文章目录

前言

一、题目描述

二、题解

三、代码

四、复杂度分析


前言

这是力扣的2477题,难度为中等,解题方案有很多种,本文讲解我认为最奇妙的一种。


一、题目描述

给你一棵 n 个节点的树(一个无向、连通、无环图),每个节点表示一个城市,编号从 0 到 n - 1 ,且恰好有 n - 1 条路。0 是首都。给你一个二维整数数组 roads ,其中 roads[i] = [ai, bi] ,表示城市 ai 和 bi 之间有一条 双向路 。

每个城市里有一个代表,他们都要去首都参加一个会议。

每座城市里有一辆车。给你一个整数 seats 表示每辆车里面座位的数目。

城市里的代表可以选择乘坐所在城市的车,或者乘坐其他城市的车。相邻城市之间一辆车的油耗是一升汽油。

请你返回到达首都最少需要多少升汽油。

示例 1:

输入:roads = [[0,1],[0,2],[0,3]], seats = 5
输出:3
解释:
- 代表 1 直接到达首都,消耗 1 升汽油。
- 代表 2 直接到达首都,消耗 1 升汽油。
- 代表 3 直接到达首都,消耗 1 升汽油。
最少消耗 3 升汽油。

示例 2:

输入:roads = [[3,1],[3,2],[1,0],[0,4],[0,5],[4,6]], seats = 2
输出:7
解释:
- 代表 2 到达城市 3 ,消耗 1 升汽油。
- 代表 2 和代表 3 一起到达城市 1 ,消耗 1 升汽油。
- 代表 2 和代表 3 一起到达首都,消耗 1 升汽油。
- 代表 1 直接到达首都,消耗 1 升汽油。
- 代表 5 直接到达首都,消耗 1 升汽油。
- 代表 6 到达城市 4 ,消耗 1 升汽油。
- 代表 4 和代表 6 一起到达首都,消耗 1 升汽油。
最少消耗 7 升汽油。

示例 3:

输入:roads = [], seats = 1
输出:0
解释:没有代表需要从别的城市到达首都。

提示:

  • 1 <= n <= 105
  • roads.length == n - 1
  • roads[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • roads 表示一棵合法的树。
  • 1 <= seats <= 105

二、题解

本题用的贪心 + DFS解题。

这道题其实是要找到 树结构中所有节点到根节点的最小开销和 。

题目中的每个城市其实就是树结构中的一个节点,除了根节点外,每个节点都要从自身出发到达根节点,这其实就是根节点到每个节点的路径。【深度优先搜索先准备着】

每个节点之间一辆车的转移的开销为 1,我们要让开销和最小,那么就要使每个节点之间的转移车尽量的少。

那么怎么安排每个节点之间转移的车辆数呢,我们可以统计途径每个节点的代表人数有多少个,这些代表从当前节点往根节点方向转移到下一个节点【树结构,只有一种转移方式】需要车辆数,一定是 代表人数除以车的容量然后向上取整。

经过每个节点的代表人数就 是以这个节点为根的子树的节点数 , 我们可以通过深度优先搜索递归处理时, 返回当前节点为根的子树的节点数。

注意:

通过向下取整得到向上取整的策略:

本文用的是Math.ceil()方法,或者你也可以使用 (m + n - 1) / n,原理就不推导了。

根节点不转移:

深度优先搜索的递归中, 对城市 0, 其没有要转移的下一个节点, 因此不能计算转移消耗的汽油数。


三、代码

Java版本:

class Solution {
    //测试代码
    public static void main(String[] args) {
        int[][] roads = {{0, 1}, {0, 2}, {0, 3}};
        int seats = 5;
        long fuel = minimumFuelCost(roads, seats);
        System.out.println(fuel);
    }

    private static long fuel = 0;//耗油量

    public static long minimumFuelCost(int[][] roads, int seats) {
        int n = roads.length + 1;
        List<List<Integer>> tree = new ArrayList<>();//生成树结构
        for (int i = 0; i < n; i++) {
            tree.add(new ArrayList<>());
        }
        for (int[] r : roads) {//把每个国家的邻居存入小list,本国是大list,例如{{123}},代表0国,邻国123
            tree.get(r[0]).add(r[1]);
            tree.get(r[1]).add(r[0]);
        }
        boolean[] visited = new boolean[n];//标记城市是否遍历
        visited[0] = true;//初始标记首都已遍历
        dfs(0, tree, visited, seats);//从0节点开始深度优先搜索寻找每一条路径
        return fuel;
    }

    private static int dfs(int city, List<List<Integer>> tree, boolean[] visited, int seats) {
        int people = 1;//每座城市初始一个代表
        for (int neighbor : tree.get(city)) {//遍历邻国
            if (!visited[neighbor]) {
                visited[neighbor] = true;//标记遍历成功
                people += dfs(neighbor, tree, visited, seats);// 累加到达当前城市的代表人数
            }
        }
        if (city != 0) {// city 不为 0 ,就需要在移动到下一个节点,people 个代表需要的车辆数等于 people ÷ seats 向上取整
            fuel += Math.ceil((double) people / seats);//每辆车消耗1汽油
        }
        return people;
    }
}

C++版本:

class Solution {
public:
    long long minimumFuelCost(vector<vector<int>>& roads, int seats) {
        int n = roads.size() + 1;
        vector<int> g[n];
        for (auto& e : roads) {
            int a = e[0], b = e[1];
            g[a].emplace_back(b);
            g[b].emplace_back(a);
        }
        long long ans = 0;
        function<int(int, int)> dfs = [&](int a, int fa) {
            int sz = 1;
            for (int b : g[a]) {
                if (b != fa) {
                    int t = dfs(b, a);
                    ans += (t + seats - 1) / seats;
                    sz += t;
                }
            }
            return sz;
        };
        dfs(0, -1);
        return ans;
    }
};

 Python3版本:

class Solution:
    def minimumFuelCost(self, roads: List[List[int]], seats: int) -> int:
        def dfs(a: int, fa: int) -> int:
            nonlocal ans
            sz = 1
            for b in g[a]:
                if b != fa:
                    t = dfs(b, a)
                    ans += ceil(t / seats)
                    sz += t
            return sz

        g = defaultdict(list)
        for a, b in roads:
            g[a].append(b)
            g[b].append(a)
        ans = 0
        dfs(0, -1)
        return ans


四、复杂度分析

时间复杂度 O(n),空间复杂度 O(n)。其中 n 为节点数。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1298129.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tomcat源码学习记录

tomcat 学习记录 tomcat 编译ant 下载编译运行 源码Debug运行 Bootstrap运行Tomcat查看状态 pom.xml测试EmbeddedTomcat 参考书籍博客 tomcat 编译 下载 tomcat 10 源码&#xff0c;解压然后idea导入 包存放的默认位置如下&#xff1a;base.path${user.home}/tomcat-build-lib…

Linux升级nginx版本

处于漏洞修复目的服务器所用nginx是1.16.0版本扫出来存在安全隐患&#xff0c;需要我们升级到1.17.7以上。 一般nginx默认在 /usr/local/ 目录&#xff0c;这里我的nginx是自定义的路径安装在 /app/weblogic/nginx 。 1.查看生产环境nginx版本 cd /app/weblogic/nginx/sbin/…

class065 A星、Floyd、Bellman-Ford与SPFA【算法】

class065 A星、Floyd、Bellman-Ford与SPFA【算法】 2023-12-9 19:27:02 算法讲解065【必备】A星、Floyd、Bellman-Ford与SPFA code1 A*算法模版 // A*算法模版&#xff08;对数器验证&#xff09; package class065;import java.util.PriorityQueue;// A*算法模版&#xff…

Elon Musk艾隆・马斯克的聊天机器人Grok上线可以使用啦,为X Premium Plus订阅者推出

艾隆・马斯克旗下的 AI 初创公司X&#xff08;前身“推特”&#xff09;开发的 ChatGPT 竞争对手 Grok 已经在 X 平台上正式推出。Grok 是一个基于生成模型 Grok-1的聊天机器人&#xff0c;它能够回答问题并提供最新的信息。与其他聊天机器人不同&#xff0c;Grok 可以实时获取…

luceda ipkiss教程 44:在PyCharm 中设置Template text

通过设置Template text&#xff0c;可以提升写代码的速度和版图设计效率。 设置了Template text&#xff0c;在PyCharm 命令窗口输入i3后按enter建&#xff0c;就可以快速输入 from ipkiss3 import all as i3 这一段代码&#xff0c;使用起来也是非常方便&#xff1a; 设置过程…

万界星空科技mes系统中看板管理

我们很多企业现在都有大屏&#xff0c;那到底万界星空科技低代码云mes系统管理中看板管理有什么作用&#xff1f;我总结了几条: 1.提高车间的生产效率 2.有效的监控设备运行状况 3.控制生产线运行 4.增加和改善用户体验 5.提高工作效率和工作安全性

课堂练习3.4:进程的切换

3-9 课堂练习3.4:进程的切换 进程切换是支持多进程的一个关键环节,涉及到 CPU 现场的保存和恢复,本实训分析 Linux 0.11 的进程切换过程。 第1关第一次进程切换过程分析 任务描述 本关任务回答问题: 在第一次进程切换时: 1.是从几号进程切换到几号进程?0 号进程和 1 号…

人工智能大型语言模型的突破

近年来&#xff0c;随着深度学习和人工智能技术的飞速发展&#xff0c;大型语言模型在自然语言处理领域取得了巨大的突破&#xff0c;引发了广泛的关注和讨论。本文将介绍大型语言模型的发展历程、技术原理、应用场景以及未来发展趋势。 一、发展历程大型语言模型的发展可以追…

Android : Xui- RecyclerView+BannerLayout 轮播图简单应用

实例图&#xff1a; 1.引用XUI http://t.csdnimg.cn/Wb4KR 2.创建显示图片布局 banner_item.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"…

综述 2017-Genome Biology:Alignment-free sequence comparison

Zielezinski, Andrzej, et al. "Alignment-free sequence comparison: benefits, applications, and tools." Genome biology 18 (2017): 1-17. https://genomebiology.biomedcentral.com/articles/10.1186/s13059-017-1319-7 被引次数&#xff1a;476应用问题&…

【九】spring、springmvc、springboot、springcloud

spring、springmvc 、springboot 、springcloud 简介 从事IT这么些年&#xff0c;经历了行业技术的更迭&#xff0c;各行各业都会有事务更新&#xff0c;IT行业技术更迭速度快的特点尤为突出&#xff0c;或许这也是从事这个行业的压力所在&#xff0c;但另一方面反应了这个行业…

利用jdbc对数据库进行增删改查

步骤/过程&#xff1a; 1&#xff0c;导入驱动包 2&#xff0c;加载驱动包 3&#xff0c;输入信息&#xff0c;进行数据库连接 4&#xff0c;创建 statement对象 5&#xff0c;执行sql语句 6&#xff0c;如果是查询操作&#xff0c;利用ResultSet处理数据&#xf…

【动手学深度学习】(十一)池化层+LeNet

文章目录 一、池化层1.理论知识2.代码 二、LeNet1.理论知识2.代码实现 【相关总结】nn.MaxPool2d() 卷积层对位置比较敏感 一、池化层 1.理论知识 二维最大池化 填充、步幅和多个通道 池化层与卷积层类似&#xff0c;都具有填充和步幅没有可学习的参数在每个输入通道应用池…

【出现模块node_modules里面包找不到】

#pic_center R 1 R_1 R1​ R 2 R^2 R2 目录 一、出现的问题二、解决办法三、其它可供参考 一、出现的问题 在本地运行 npm run docs:dev之后&#xff0c;出现 Error [ERR_MODULE_NOT_FOUND]: Cannot find package Z:\Blog\docs\node_modules\htmlparser2\ imported from Z:\Blo…

CCF计算机软件能力认证202309-1坐标变换(其一)(C语言)

ccf-csp计算机软件能力认证202309-1坐标变换&#xff08;其一&#xff09;(C语言版) 题目内容&#xff1a; 问题描述 输入格式 输出格式 样例输入 3 2 10 10 0 0 10 -20 1 -1 0 0样例输出 21 -11 20 -10样例解释 评测用例规模与约定 解题思路 1.第一步分析问题&…

Redux Toolkit(RTK)在React tsx中的使用

一个需求: header组建中有一个搜索框,然后这个搜索框在其他页面路由上都可以使用:例如这两个图共用顶部的搜索框; 我之前的做法就是组建传值, 在他们header 组建和 PageA ,B 的父级组件上定一个值,然后顶部变化传到父级组件,在从父级组件传到page组件,有点繁琐,现在说一下利用…

Javaweb之 依赖管理的详细解析

04. 依赖管理 4.1 依赖配置 依赖&#xff1a;指当前项目运行所需要的jar包。一个项目中可以引入多个依赖&#xff1a; 例如&#xff1a;在当前工程中&#xff0c;我们需要用到logback来记录日志&#xff0c;此时就可以在maven工程的pom.xml文件中&#xff0c;引入logback的依…

16.Java程序设计-基于SSM框架的android餐厅在线点单系统App设计与实现

摘要&#xff1a; 本研究旨在设计并实现一款基于SSM框架的Android餐厅在线点单系统&#xff0c;致力于提升餐厅点餐流程的效率和用户体验。通过整合Android移动应用和SSM框架的优势&#xff0c;该系统涵盖了用户管理、菜单浏览与点单、订单管理、支付与结算等多个功能模块&…

解决 Cannot read properties of undefined (reading ‘getUserMedia‘) 报错

[TOC](解决 Cannot read properties of undefined (reading ‘getUserMedia’) 报错) 0. 背景 使用浏览器输入语音时&#xff0c;浏览器的控制台里面有下面错误信息。 Cannot read properties of undefined (reading getUserMedia)1. 解决方法 在浏览器中访问 chrome://fla…

AVFormatContext编解码层:理论与实战

文章目录 前言一、FFmpeg 解码流程二、FFmpeg 转码流程三、编解码 API 详解1、解码 API 使用详解2、编码 API 使用详解 四、编码案例实战1、示例源码2、运行结果 五、解码案例实战1、示例源码2、运行结果 前言 AVFormatContext 是一个贯穿始终的数据结构&#xff0c;很多函数都…