Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >LeetCode 1489. 找到最小生成树里的关键边和伪关键边(并查集+kruskal最小生成树)

LeetCode 1489. 找到最小生成树里的关键边和伪关键边(并查集+kruskal最小生成树)

作者头像
Michael阿明
发布于 2021-02-19 06:55:01
发布于 2021-02-19 06:55:01
99000
代码可运行
举报
运行总次数:0
代码可运行

文章目录

1. 题目

给你一个 n 个点的带权无向连通图,节点编号为 0 到 n-1 ,同时还有一个数组 edges ,其中 edges[i] = [fromi, toi, weighti] 表示在 fromi 和 toi 节点之间有一条带权无向边。

最小生成树 (MST) 是给定图中边的一个子集,它连接了所有节点且没有环,而且这些边的权值和最小。

请你找到给定图中最小生成树的所有关键边和伪关键边。

  • 如果从图中删去某条边,会导致最小生成树的权值和增加,那么我们就说它是一条关键边。
  • 伪关键边则是可能会出现在某些最小生成树中但不会出现在所有最小生成树中的边。

请注意,你可以分别以任意顺序返回关键边的下标和伪关键边的下标。

示例 1:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入:n = 5, edges = [[0,1,1],[1,2,1],[2,3,2],[0,3,2],[0,4,3],[3,4,3],[1,4,6]]
输出:[[0,1],[2,3,4,5]]

解释:上图描述了给定图。 下图是所有的最小生成树。

注意到第 0 条边和第 1 条边出现在了所有最小生成树中,所以它们是关键边,我们将这两个下标作为输出的第一个列表。 边 2,3,4 和 5 是所有 MST 的剩余边,所以它们是伪关键边。我们将它们作为输出的第二个列表。

示例 2 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入:n = 4, edges = [[0,1,1],[1,2,1],[2,3,1],[0,3,1]]
输出:[[],[0,1,2,3]]
解释:可以观察到 4 条边都有相同的权值,
任选它们中的 3 条可以形成一棵 MST 。所以 4 条边都是伪关键边。
 
提示:
2 <= n <= 100
1 <= edges.length <= min(200, n * (n - 1) / 2)
edges[i].length == 3
0 <= fromi < toi < n
1 <= weighti <= 1000
所有 (fromi, toi) 数对都是互不相同的。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

图–最小生成树 并查集参考

  • 解题见注释
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class dsu{  //并查集
    vector<int> f;
public:
    dsu(int n)
    {
        f.resize(n);
        for(int i = 0; i < n; ++i)
            f[i] = i;
    }
    void merge(int a, int b)
    {
        int fa = find(a), fb = find(b);
        if(fa != fb)
        {
            f[fa] = fb;
        }
    }
    int find(int a)
    {
        if(a == f[a]) return a;
        return f[a] = find(f[a]);
    }
    void reset()
    {
        for(int i = 0; i < f.size(); ++i)
            f[i] = i;
    }
};
class Solution {
public:
    vector<vector<int>> findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) {
        vector<int> edgeId(edges.size());
        iota(edgeId.begin(), edgeId.end(), 0);
        sort(edgeId.begin(), edgeId.end(),[&](auto a, auto b){
            return edges[a][2] < edges[b][2];//距离小的优先
        });
        dsu u(n);
        vector<bool> vis(edges.size(), false);
        int mincost = kruskal(vis, u, edgeId, edges, n, 0);//最小生成树权值
        vector<vector<int>> ans(2);
        for(int i = 0; i < edges.size(); ++i)
        {
            vis[i] = true;//删除这条边
            u.reset();//重置并查集
            int cost = kruskal(vis, u, edgeId, edges, n, 0);
            if(cost > mincost)//删除边以后,cost 变大,或 无法生成树
            {
                ans[0].push_back(i);//关键边
                vis[i] = false;
                continue;
            }
            u.reset();//重置并查集
            u.merge(edges[i][0], edges[i][1]);//不是关键边,且提前把这条边加入树中
            cost = kruskal(vis, u, edgeId, edges, n, edges[i][2]);
            if(cost == mincost)// 权值和 不变,伪关键边
                ans[1].push_back(i);
            vis[i] = false;//恢复这条边
        }
        return ans;
    }
    int kruskal(vector<bool>& vis, dsu& u, vector<int>& edgeId, vector<vector<int>>& edges, int n, int mincost)
    {
        int edge_count = (mincost ? 1 : 0);//提前加入边了吗
        int a, b, id, cost;
        for(int i = 0; i < edgeId.size(); ++i)
        {
            id = edgeId[i];
            if(vis[id]) continue;//边删除了
            a = edges[id][0];
            b = edges[id][1];
            cost = edges[id][2];
            if(u.find(a) != u.find(b))
            {
                u.merge(a, b);
                mincost += cost;
                edge_count++;
            }
            if(edge_count == n-1)
                return mincost;
        }
        return INT_MAX;//无法构造生成树
    }
};

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/01/21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
在Ubuntu 18.04 LTS安装ROS 2 Bouncy版机器人操作系统
ROS 1和ROS 2同步开发发行,目前最新ROS 1的版本号为M,而ROS 2的版本号为B,ROS 2 Bouncy正式发布。
zhangrelay
2019/01/23
2.6K0
ROS2机器人编程简述humble-第二章-First Steps with ROS2 .1
第二章主要就是一些ROS的基本概念,其实ROS1和ROS2的基本概念很多都是类似的。
zhangrelay
2023/02/03
5370
ROS 1 和 ROS 2 的前世、今生、安装使用说明与资料汇总
现在,最常用的ROS indigo或ROS Kinetic等都是1.0时代的ROS,这个时代的ROS有一个master(roscore)。
zhangrelay
2019/01/23
3.1K0
使用机器人操作系统ROS 2和仿真软件Gazebo 9命令遥控可视化教程(二)
ROS2入门介绍参考:https://zhuanlan.zhihu.com/p/96940278
zhangrelay
2020/02/24
1.5K0
使用机器人操作系统ROS 2和仿真软件Gazebo 9命令遥控可视化教程(二)
ROS2极简总结-命令行接口基础
ros2 <main_command> <sub_command> <<arguments>>
zhangrelay
2021/12/02
1.6K0
ROS2极简总结-命令行接口基础
[ROS2基础]参数和动作
https://gitee.com/shoufei/ros2_galactic_turorials.git
首飞
2022/05/22
8590
[ROS2基础]参数和动作
ROS2网络多机通信DDS和安全加密SROS(多机器人系统)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
zhangrelay
2019/10/22
3.9K0
ROS2网络多机通信DDS和安全加密SROS(多机器人系统)
ROS 2 Humble Hawksbill 命令基础
ros2 -h 用法:ros2 [-h] [--use-python-default-buffering] 调用 `ros2 <command> -h` 以获得更详细的用法。 
zhangrelay
2022/05/27
7770
ROS 2 Humble Hawksbill 命令基础
ROS2机器人f1tenth之CLI工具基础
~/ros_ws/f1tenth_gym_ros$ source install/setup.sh
zhangrelay
2022/06/30
4630
ROS2机器人f1tenth之CLI工具基础
ROS2机器人编程简述humble-第二章-Parameters .3.4
ROS中的参数与各个节点相关。参数用于在启动时(以及运行时)配置节点,而无需更改代码。参数的生存期与节点的生存期相关联(尽管节点可以实现某种持久性以在重新启动后重新加载值)。
zhangrelay
2023/02/10
7690
ROS2机器人编程简述humble-第二章-Parameters .3.4
机器人编程趣味实践14-机器人三维仿真(Gazebo+TurtleBot3)
TurtleBot3支持仿真开发环境,可以在仿真中用虚拟机器人编程开发。 有两种开发环境可以做到这一点,一种是使用带有 3D 可视化工具 RViz 的假节点,另一种是使用 3D 机器人模拟器 Gazebo。
zhangrelay
2021/12/02
8710
机器人编程趣味实践14-机器人三维仿真(Gazebo+TurtleBot3)
ROS 2 Eloquent Elusor安装和使用汇总
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
zhangrelay
2019/11/18
1.5K0
ROS2编程基础课程--arguments
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
zhangrelay
2019/09/19
1.2K0
ROS2编程基础课程--概念
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
zhangrelay
2019/09/18
8090
计算机操作系统(OS)安装机器人操作系统(ROS)实现物联网功能
博客中大量介绍了将Ubuntu等Linux系统借助机器人操作系统ROS实现机器人控制设计开发和物联网功能案例,并可基于OpenAI等实现人工智能相关训练。
zhangrelay
2021/03/03
2.1K0
ROS2机器人笔记2106
ROS虚拟机器人竞赛,优势低成本切入,使用Gazebo! 关注 vrx-2022 robotx.org image.png rosbag1和rosbag2高效转换库。 ROS2 wiki案例很多情况下会搜索到ROS1案例。 Dashing停止维护,目前Foxy还剩24个月,Galactic已经发布。 image.png ROS2教程多起来了,官网文档仍然是比较好的,维护比较及时。 如果已经有很多ROS1代码,切换ROS2,意味着必须重写很多节点。 rospy2,tf_transformations
zhangrelay
2021/07/04
6840
ROS2机器人笔记2106
ROS2机器人实验报告提示01➡入梦⬅
开启终端:ctrl+alt+t,新开标签tab:ctrl+shift+t,在终端结束进程:crtl+c 。
zhangrelay
2021/12/02
4800
【机器人】开发系统镜像制作指南
注意:以下的操作均在虚拟机上完成。虚拟机可以使用免费的Virtual Box或者相对高级的VMare。
杨丝儿
2022/03/01
1.7K0
[ROS2基础]launch 文件和多节点进程
launch文件可以同时配置和启动多个ros节点。ROS2中的launch文件可以用Python、xml、yaml来写。
首飞
2022/05/29
2.3K0
[ROS2基础]launch 文件和多节点进程
ROS机器人操作系统新发布软件包摘录--(2018.03)
1 https://wiki.ros.org/vtec_ros 2 https://github.com/lukscasanova/vtec_ros 。
zhangrelay
2022/04/29
1.4K0
ROS机器人操作系统新发布软件包摘录--(2018.03)
推荐阅读
相关推荐
在Ubuntu 18.04 LTS安装ROS 2 Bouncy版机器人操作系统
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验