【LeetCode】882. 细分图中的可到达节点

news2025/7/5 10:53:01

题目描述

给你一个无向图(原始图),图中有 n 个节点,编号从 0 到 n - 1 。你决定将图中的每条边 细分 为一条节点链,每条边之间的新节点数各不相同。
图用由边组成的二维数组 edges 表示,其中 edges[i] = [ui, vi, cnti] 表示原始图中节点 ui 和 vi 之间存在一条边,cnti 是将边 细分 后的新节点总数。注意,cnti == 0 表示边不可细分。
要 细分 边 [ui, vi] ,需要将其替换为 (cnti + 1) 条新边,和 cnti 个新节点。新节点为 x1, x2, …, xcnti ,新边为 [ui, x1], [x1, x2], [x2, x3], …, [xcnti+1, xcnti], [xcnti, vi] 。
现在得到一个 新的细分图 ,请你计算从节点 0 出发,可以到达多少个节点?如果节点间距离是 maxMoves 或更少,则视为 可以到达 。
给你原始图和 maxMoves ,返回 新的细分图中从节点 0 出发 可到达的节点数 。

示例 1:

在这里插入图片描述
输入:edges = [[0,1,10],[0,2,1],[1,2,2]], maxMoves = 6, n = 3
输出:13
解释:边的细分情况如上图所示。
可以到达的节点已经用黄色标注出来。

示例 2:

输入:edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], maxMoves = 10, n = 4
输出:23

示例 3:

输入:edges = [[1,2,4],[1,4,5],[1,3,1],[2,3,4],[3,4,5]], maxMoves = 17, n = 5
输出:1
解释:节点 0 与图的其余部分没有连通,所以只有节点 0 可以到达。

提示:

0 <= edges.length <= min(n * (n - 1) / 2, 104)
edges[i].length == 3
0 <= ui < vi < n
图中 不存在平行边
0 <= cnti <= 104
0 <= maxMoves <= 109
1 <= n <= 3000

方法一:Dijkstra

class Solution {
public:
    int encode(int u, int v, int n){
        return u * n + v;
    }
    int reachableNodes(vector<vector<int>>& edges, int maxMoves, int n) {
        // 将输入的edges转换成邻接表adList
        vector<vector<pair<int, int>>> adList(n);
        for (auto &edge : edges) {
            int u = edge[0], v = edge[1], nodes = edge[2];
            adList[u].emplace_back(v, nodes);
            adList[v].emplace_back(u, nodes);
        }

        unordered_map<int, int> used;
        //unordered_set:无序 set 容器
        unordered_set<int> visited;
        int res = 0; // 记录可达节点数

        // priority_queue 优先级队列,优先级最大的出队
        // priority_queue<Type, Container, Functional>
        // Functional默认是less 降序,greater 升序队列
        // pair的比较,先比较第一个元素,第一个相等比较第二个
        // 因此这里的意思是,一个元素为pair<int,int>的升序队列
        // 每次取出的都是值最小的键值对
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
        // pair<step, node>
        // 表示节点0到起点0的step = 0
        pq.emplace(0, 0); // emplace原地构造一个元素并插入队列

        // 当 pq 不为空 且 step <= maxMoves
        while(!pq.empty() && pq.top().first <= maxMoves){
            auto [step, u] = pq.top();
            pq.pop();
            // u 已经被访问过
            if(visited.count(u)){
                continue;
            }
            // u 没有被访问过
            visited.emplace(u);
            // 只考虑原始节点是不是可达节点
            // 不考虑细分节点是不是可达节点
            res ++; // 则u是可达节点

            // 遍历u的邻接节点,加入pq队列
            for (auto [v, nodes] : adList[u]){
                // nodes 是 u 和 v 之间的细分节点
                // step 指的是起点0到当前节点的距离
                // 如果noded + step + 1 < maxMoves ,说明是可达节点
                // !visited.count(v),说明未被访问
                // 把节点 0 -> v 这一条路线加入考虑
                // 也就是说可以通过这个路线考虑多包含一个节点
                if(nodes + step + 1 <= maxMoves && !visited.count(v)){
                    pq.emplace(nodes + step + 1, v);
                    // 更新了step = nodes + step + 1 
                }
                // 记录各条边上的细分节点的可达情况
                // used key: u -> v 的边
                // 比如节点0 到其他节点的边标记为 0*3+1=1, 0*3+2=2
                // value: 这条边上的细分节点数
                // 也就是说 used存储了u->v 的细分节点数
                used[encode(u, v, n)] = min(nodes, maxMoves - step);
            }
        }

        for (auto &edge : edges){
            int u = edge[0], v = edge[1], nodes = edge[2];
            // 比较 u->v 和 v->u 的可达节点数
            // 因为这两条路线只可能计算一次,因此选择最小的
            res += min(nodes, used[encode(u, v, n)] + used[encode(v, u, n)]);
        }
        return res;
    }
};

心得

  • 看到是难度是 困难 + 图,直接看题解了。

方法:Dijsktra算法

  • 当图中只存在原始节点而不存在细分节点时,此题可以用 Dijkstra算法 解决: 将输入的 edges 转换成邻接表 adList,维护一个小顶堆 pq 可以依次计算出图中的起点到各个点最短路径,从而计算出可到达节点。 pq 中的元素为节点以及起点到该节点的路径长度,并以路径长度为比较元素。每次取出未访问过的节点中的路径最短的节点,并访问其邻接点,若路径长度仍小于等于 maxMoves 且未访问过,可将其放入 pq,直到 pq 为空 或 pq 最短路径大于 maxMoves
  • 但当每条边都加入细分节点后,需要考虑细分节点是否可达。用一个哈希表 used 记录各条边上的细分节点的可达情况,键为二元点对 (u,v),表示从点 u 到点 v 的边,值为这条边上的可达细分节点数。注意在计算细分节点时,考虑单向的情况,分别计算 used[(u,v)] 和 used[(v,u)],并且这两个值不一定相等。计算 used 时,是要在访问路径最短的节点 u 的邻接节点 v 时计算。如果邻接节点的路径长度小于等于 maxMoves ,说明这条边上的细分节点都可达,否则只有一部分可达,并且这部分细分节点是靠近节点 u 的。
  • 计算总的可达节点时,需要加上细分节点的部分。但是每条边上的细分节点可能会被计算过两次,即 used[(u,v)] 和 used[(v,u)] ,他们分别是靠近 u 开始计算的和靠近 v 开始计算的,需要去掉这两部分重叠的细分节点。

参考资料

  1. Dijikstra算法详解
  2. priority_queue用法详解

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

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

相关文章

ESG,TO B长期主义里的「新战役」

中国企业最好的方式是从初始阶段就植入ESG基因&#xff0c;使它逐渐从隐形变成显性基因。长期坚持此类发展导向&#xff0c;对后续发展ESG战略&#xff0c;提升ESG合规能力也将成为一种积累和准备。 作者|三七 编辑|皮爷 出品|产业家 20世纪初期&#xff0c;伦敦得到一个延…

MyBaits-Plus中@TableField和@TableId用法

目录 前言 一、TableField(value "表字段") 二、TableField(select false) 三、TableField(exist false) 四、TableId(type IdType.AUTO)补充 总结 前言 接着前两篇mybatis-plus的知识点 Mybatis-Plus知识点[MyBatisMyBatis-Plus的基础运用]_心态还需努力呀…

论文阅读: Disentangled lmage Colorization via Global Anchors

Disentangled lmage Colorization via Global Anchors发表于SIGGRAPH ASIA 2022&#xff0c;是一篇基于深度学习的图像彩色化的工作&#xff0c;简单介绍一下。之前曾分享过一篇彩色化的经典论文&#xff1a;经典论文回顾: Colorization using Optimization。 作者认为图像彩色…

【数据库】索引

MySQL索引 1、B树索引 是InnoDB引擎默认的索引 B树结构 B树是平衡树&#xff0c;即所有叶子节点都在同一层的多叉树 每个节点中key和指针交替排列&#xff0c;两个key之间的指针指向的是大于等于左边key且小于等于右边key的节点 叶子节点顺次连接&#xff0c;所以沿着B树的叶…

ADAU1860调试心得(5)ADC-DAC直通程序

硬件、驱动全部都搞好了&#xff0c;我觉得调试记录的话&#xff0c;就从最简单的开始&#xff0c;先做一个直通的例程。先把这个板子弄出声来&#xff0c;会用sigmastudio&#xff0c;会做ADAU开发的兄弟们应该很熟悉&#xff0c;同样的配方&#xff0c;同样的味道&#xff0c…

Nginx--单向链表分析

1.基本数据结构 1.1结点 struct ngx_list_part_s {void *elts;ngx_uint_t nelts;ngx_list_part_t *next; };结构成员分析 void* elts :数组元素指针 ngx_uint_t :数组里面的元素数量 ngx_list_part_t*…

英文Assignment写作引用格式怎么分析?

英文Assignment写作中我们常常使用不同作家和研究员的观点&#xff0c;论证来支持自己的想法。引用他们原文的时候我们必须使用具体引用格式。不同学校对引用格式都有不同的要求。事实上&#xff0c;有很多不同的引用格式&#xff0c;大约有超过200种引用格式。例如我们耳熟能详…

一文读懂!异常检测全攻略!从统计方法到机器学习

&#x1f4a1; 作者&#xff1a;韩信子ShowMeAI &#x1f4d8; 数据分析实战系列&#xff1a;https://www.showmeai.tech/tutorials/40 &#x1f4d8; 机器学习实战系列&#xff1a;https://www.showmeai.tech/tutorials/41 &#x1f4d8; 本文地址&#xff1a;https://showmea…

Day12--优化分类页面的效果

1.提出一个问题&#xff0c;当你点击一级分类的时候&#xff0c;在三级分类中滚动自己的进度条。切换到之后的另一级分类再看看其三级分类时不是再最顶部。 我的操作&#xff1a; 1》在cate.vue中&#xff1a; *************************************************************…

大数据必看:大厂十年架构师职业生涯实战经验总结,《大规模分布式系统架构与设计实战》

前言 这段时间一直在读一本书《大规模分布式系统架构与设计实战》&#xff0c;这是淘宝千峰老师的作品&#xff0c;是从程序员到首席架构师十多年职业生涯的实战经验总结。 这本书其实是围绕着Fourinone在讲分布式&#xff0c;并非分布式理论&#xff0c;所以只适用于想研究F…

【allegro 17.4软件操作保姆级教程五】布线前准备之过孔、差分对、布线集合添加

目录 1.1 过孔添加与设置 1.2 添加差分对 1.3 添加布线集合 1.1 过孔添加与设置 布线换层时需要由过孔贯穿&#xff0c;而软件本身是没有过孔可以直接调用的&#xff0c;所以需要手动添加和设置。一般我们使用的都是通孔&#xff0c;盲孔和埋孔成本高&#xff0c;一般不使用。…

PG::Photography

nmap -Pn -p- -T4 --min-rate1000 192.168.171.76 nmap -Pn -p 22,80,139,445,8000 -sCV 192.168.171.76 查看8000端口的内容 CMS的关键字“Built with Koken” 存在的漏洞需要认证 https://www.exploit-db.com/exploits/48706 在端口枚举时&#xff0c;该靶机有smb服务&am…

MyBatis-Plus之DML编程控制

1. id生成策略控制 前面我们在新增的时候留了一个问题&#xff0c;就是新增成功后&#xff0c;主键ID是一个很长串的内容&#xff0c;我们更想要的是按照数据库表字段进行自增长&#xff0c;在解决这个问题之前&#xff0c;我们先来分析下ID该如何选择&#xff1a; 不同的表应…

vscode一键生成佛祖保佑永无bug

工欲善其事&#xff0c;必先利其器 今天给大家分享一个vscode注释插件-koroFileHeader&#xff0c;可以快速给我们的文件和函数添加注释&#xff0c;快来看看吧 安装 打开vscode拓展&#xff0c;搜索“koroFileHeader”&#xff0c;安装&#xff0c;重新启动一下 使用 快捷键 生…

【配置nacos】使用application.yml配置文件来配置spring-cloud-starter-alibaba-nacos-config

1.首先修改pom.xml文件&#xff0c;引入spring-cloud-starter-alibaba-nacos-config依赖 <!--Nacos配置管理--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><…

Java#26(常见算法: 排序算法)

目录 一.冒泡排序 相邻元素之间两两比较,大的放右边,小的放左边 二.选择排序 从0索引开始,拿着每一个索引上的元素和后面的元素依次标胶,小的放在前面,大的放在后面 三.插入排序 假如0到n索引的数据遵循从小到大排序,就可以将0-n看做有序的,则n1到最大索引都是无序的 四…

【日常系列】LeetCode《19·BFS 和 DFS》

数据规模->时间复杂度 <10^4 &#x1f62e;(n^2) <10^7:o(nlogn) <10^8:o(n) 10^8<:o(logn),o(1) 内容 lc 589 &#xff1a;N 叉树的前序遍历 https://leetcode.cn/problems/n-ary-tree-preorder-traversal/ 提示&#xff1a; 节点总数在范围 [0, 104]内 0 &l…

最简单的git图解(git rebase)

今天我们来讲解下git rebase命令&#xff0c;以及git rebase命令与git merge命令的区别。 git rebase图解&#xff1a; 假设我们目前有master、demo两个分支&#xff0c;而且demo分支上从master分支上切出来的&#xff1a; 从上图中可以看到&#xff0c;我们从C2提交点切出来了…

图像边缘检测与图像分割常用算法研究分析-含Matlab代码

⭕⭕ 目 录 ⭕⭕✳️ 引言✳️ 一、经典边缘检测算子✳️ 1.1 Roberts 算子与实验验证✳️ 1.2 Sobel 算子原理与实验验证✳️ 1.3 Prewitt 算子与实验验证✳️ 1.4 Log 算子与实验验证✳️ 1.5 Canny 算子与实验验证✳️ 二、图像分割原理及其实验验证✳️ 2.1 基于阈值处理的…

用 AWTK 和 AWPLC 快速开发嵌入式应用程序 (5)- 自定义功能块(下)

AWPLC 目前还处于开发阶段的早期&#xff0c;写这个系列文章的目的&#xff0c;除了用来验证目前所做的工作外&#xff0c;还希望得到大家的指点和反馈。如果您有任何疑问和建议&#xff0c;请在评论区留言。 1. 背景 AWTK 全称 Toolkit AnyWhere&#xff0c;是 ZLG 开发的开源…