最小生成树,Kruskal算法

news2024/11/21 0:18:39

最小生成树(Minimum Spanning Tree,简称 MST)是一个连通图的子图,它包含图中的所有节点,并且是一个树(无环连通图),同时保证连接所有节点的边的权重之和最小。

在一个带权重的连通图中,有许多不同的方式可以连接所有节点,但最小生成树的概念强调的是选择最小权重的边,以使整个树的总权重最小。

有两种常见的算法用于求解最小生成树问题:Prim 算法和 Kruskal 算法。

1、Prim 算法:Prim 算法从一个起始节点开始,逐步地选择连接当前生成树和非树节点的最小权重边,将该节点添加到生成树中,直到所有节点都被包含在生成树中。
2、 Kruskal 算法:Kruskal 算法首先将所有边按照权重从小到大排序,然后从最小权重的边开始逐个加入生成树,但是要保证不形成环路,即所加入的边的两个节点不能在同一个集合中。

ps:Kruskal 算法使用到了 并查集!

1584. 连接所有点的最小费用

给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。

连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。

请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。

在这里插入图片描述

解法

根据题意,我们得到了一张n个节点的完全图,任意两点之间的距离均为它们的曼哈顿距离。现在我们需要在这个图中取得一个子图,恰满足子图的任意两点之间有且仅有一条简单路径,且这个子图的所有边的总权值之和尽可能小。

能够满足任意两点之间有且仅有一条简单路径只有树,且这棵树包含 n 个节点。我们称这棵树为给定的图的生成树,其中总权值最小的生成树,我们称其为最小生成树。

最小生成树有一个非常经典的解法:Kruskal

代码如下:

// 定义了 DisjointSetUnion类,这是一个并查集类,用来管理节点的集合关系
class DisjointSetUnion{
private: // 在 private 下的成员变量和函数只能在 类的内部 访问
    vector<int> f,rank;
    int n;

public:
    //  构造函数
    DisjointSetUnion(int _n){
        // n个节点
        n = _n;
        rank.resize(n,1);
        f.resize(n);
        for(int i = 0;i<n;i++){
            f[i] = i;
        }
    }

    // 并查集
    int find(int x){
        // 路径压缩优化
        return f[x]==x? x:f[x]=find(f[x]);
    }

    //  判断x和y是否在一个集合中,如果已经在一个集合了,返回false
    // 如果不在一个集合中,通过rank进行合并
    int unionSet(int x,int y){
        int fx = find(x), fy = find(y);
        if(fx == fy){
            return false;
        }
        if(rank[fx] < rank[fy]){
            f[fx] = fy;
        }else if(rank[fx]>rank[fy]){
            f[fy] = fx;
        }else {
            f[fx] = fy;
            rank[fy]++;
        }
        return true;
    }
};

// 定义结构体Edge
struct Edge{
    int len,x,y;
    // 是一个构造函数 Edge,用来构造Edge对象
    // 通过 len(len), x(x) 和 y(y),将传入的参数分别赋值给结构体的成员变量
    Edge(int len,int x,int y):len(len),x(x),y(y){
    }
};

class Solution {
public:
    int minCostConnectPoints(vector<vector<int>>& points) {
        //  lambda 函数
        // [&] 表示 lambda 函数通过引用捕获外部作用域中的变量,
        // 这意味着在 lambda 函数内部, 可以访问外部作用域中的变量。
        // 计算x和y这两个点之间的曼哈顿距离
        auto dist = [&](int x,int y)-> int {
            return abs(points[x][0] - points[y][0]) 
                                + abs(points[x][1] - points[y][1]);
        };

        int n = points.size();
        // 创建了一个名为 dsu 的 DisjointSetUnion 类的对象
        DisjointSetUnion dsu(n);

        vector<Edge> edges;
        for(int i = 0;i<n;i++){
            for(int j = i+1;j<n;j++){
                // 把每两个点之间的距离、起点、终点放入 vector中
                // dist(i, j), i, j 是用于构造 Edge 对象的参数
                edges.emplace_back(dist(i,j),i,j);
            }
        }

        // 根据权重来排序Edge,权重越小的排在前面
        sort(edges.begin(),edges.end(),[](Edge a,Edge b)->int {return a.len<b.len;});
        // num 表示已经连接的点的数量
        int ret = 0,num = 1;

        //遍历排序后的边,如果两个节点不在同一个集合中,则将它们合并,
        // 并将边的长度加入 ret,同时更新 num
        for(auto& [len,x,y]:edges){
            if(dsu.unionSet(x, y)){
                // 合并 x、y
                ret += len;
                num++;
                if(num == n){
                    break;
                }
            }
        }
        return ret;
    }
};

1135. 最低成本联通所有城市

想象一下你是个城市基建规划者,地图上有 n 座城市,它们按以 1 到 n 的次序编号。

给你整数 n 和一个数组 conections,其中 connections[i] = [xi, yi, costi] 表示将城市 xi 和城市 yi 连接所要的costi(连接是双向的)。

返回连接所有城市的最低成本,每对城市之间至少有一条路径。如果无法连接所有 n 个城市,返回 -1

该 最小成本 应该是所用全部连接成本的总和。

在这里插入图片描述
代码:

class Solution {
private:
    vector<int> father,rank;
public:
    // 路径压缩
    int Find(int n){
        return father[n] == n? father[n] : father[n] = Find(father[n]);
    }

    // 按秩合并
    int unionSet(int x,int y){
        int fx = Find(x), fy = Find(y);
        if(fx == fy) return false;
        if(rank[fx]<rank[fy]){
            father[fx] = fy;
        }else if(rank[fx]>rank[fy]){
            father[fy] = fx;
        }else {
            father[fx] = fy;
            rank[fy]++;
        }
        return true;
    }

    int minimumCost(int n, vector<vector<int>>& connections) {
        // 初始化father数组
        father.resize(n+1,0);
        for(int i = 1;i<=n;i++){
            father[i] = i;
        }
        // 初始化rank数组
        rank.resize(n+1,1);

        // 根据权重重新排一下 connections
        sort(connections.begin(),connections.end(),
        [](vector<int> a,vector<int> b){
            return a[2]<b[2];
        });

        int ans = 0, num = 1;

        for(auto conn:connections){
            if(unionSet(conn[0],conn[1])){
                // 如果不是一个集合的,进行合并
                ans += conn[2];
                num++;
            }
            if(num == n){
                break;
            }
        }
        // 如果没有联通所有的点,则返回-1
        return num == n? ans:-1;
    }
};

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

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

相关文章

R语言实现非等比例风险生存资料分析(1)

#非等比例风险的生存资料分析 ###1 生成模拟数据### library(flexsurv) set.seed(123) # 生成样本数量 n <- 100 # 生成时间数据 time <- sample(1:1000,n,replaceF) # 调整shape和scale参数以控制生存曲线形状 # 生成事件数据&#xff08;假设按比例风险模型&#xff0…

【SpringBoot】中的ApplicationRunner接口 和 CommandLineRunner接口

1. ApplicationRunner接口 用法&#xff1a; 类型&#xff1a; 接口 方法&#xff1a; 只定义了一个run方法 使用场景&#xff1a; springBoot项目启动时&#xff0c;若想在启动之后直接执行某一段代码&#xff0c;就可以用 ApplicationRunner这个接口&#xff0c;并实现接口…

YB2416是支持高电压输入的同步降压电源管理芯片

简介&#xff1a; YB2416是支持高电压输入的同步降压电源管理芯片&#xff0c;在 4~30V 的宽输入电压范围内可实现3A的连续电流输出。通过调节 FB 端口的分压电阻&#xff0c;可以输出1.8V到28V的稳定电压。YB2416具有优秀的恒压/恒流(CC/C)特性。YB2416 采用电流模式的环路控制…

UI自动化测试常见的Exception

一. StaleElementReferenceException&#xff1a; - 原因&#xff1a;引用的元素已过期。原因是页面刷新了&#xff0c;此时当然找不到之前页面的元素。- 解决方案&#xff1a;不确定什么时候元素就会被刷新。页面刷新后重新获取元素的思路不变&#xff0c;这时可以使用python的…

【云原生】【k8s】从小白到大神之路之学习运维第82天-------基于Prometheus监控Kubernetes集群

第四阶段 时 间&#xff1a;2023年8月17日 参加人&#xff1a;全班人员 内 容&#xff1a; 基于Prometheus监控Kubernetes集群 目录 一、Prometheus简介 &#xff08;一&#xff09;Prometheus的基本原理 &#xff08;二&#xff09;Prometheus优势 &#xff08;三&a…

java.security.InvalidKeyException: Illegal key size

JDK受版本安全限制&#xff0c;默认只允许128位长度以内的。秘钥长度&#xff0c;如果密钥大于128, 会抛出java.security.InvalidKeyException: Illegal key size 异常. java运行时环境默认读到的是受限的policy文件. 文件位于${java_home}/jre/lib/security, 这种限制是因为美…

【IMX6ULL驱动开发学习】06.DHT11温湿度传感器驱动程序编写与测试

一、DHT11简介 DHT11是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器&#xff0c;会测量空气中湿度&#xff0c;再根据测量结果决定是否继续加湿。 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;具有超小体积、极低功耗的特点…

配置 autofs

配置 autofs 配置 autofs&#xff0c;按照以下要求自动挂载远程用户的家目录&#xff0c;要求如下&#xff1a; host.domain8.rhce.cc ( 172.25.250.250 ) NFS 导出 /rhome 到您的系统。此文件系统包含 为用户 remoteuser1 预配置的主目录 remoteuser1 的主目录是 host.dom…

【快速解决】尝试卸载 Office 时出现错误代码 30029-4,解决office安装报错等问题,解决无法安装office的问题

目录 ​编辑 前言&#xff08;本文可以快速解决你遇到的问题&#xff09; 问题描述 解决无法安装问题的步骤分为以下两个主要阶段&#xff1a; 第一步&#xff1a;卸载现有的 Office 软件 第二步&#xff1a;安装所需的新版 Office 安装步骤如下&#xff1a; 1.启动微信…

看完《孤注一掷》:原来这类人最容易被电信诈骗!

最近&#xff0c;你看了诈骗电影《孤注一掷》吗&#xff1f; “想成功先发疯&#xff0c;不顾一切向钱冲&#xff1b;拼一次富三代&#xff0c;拼命才能不失败&#xff1b;今天睡地板&#xff0c;明天当老板&#xff01;”诈骗工厂里的被骗去打黑工的人们一次次高呼着朗朗上口…

基于Java+SpringBoot+vue前后端分离企业oa管理系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

【LangChain】P0 LangChain 是什么与准备工作

LangChain 是什么与准备工作 LangChain 是什么&#xff1f;所谓增强数据感知所谓与环境互动 Get Started下载安装 langchain下载安装 openai获取 OpenAI API Key通过名为 openai_api_key 的参数传递密钥 LangChain 是什么&#xff1f; LangChain 是一个利用语言模型开发应用程序…

YOLOv8改进后效果

数据集 自建铁路障碍数据集-包含路障&#xff0c;人等少数标签。其中百分之八十作为训练集&#xff0c;百分之二十作为测试集 第一次部署 版本&#xff1a;YOLOv5 训练50epoch后精度可达0.94 mAP可达0.95.此时未包含任何改进操作 第二次部署 版本&#xff1a;YOLOv8改进版本 首…

“智”创未来,引领信息化新风潮,数字转型再添强动力

如今企业信息化已经成为了现代商业发展的大势所趋。信息化的浪潮不但带来了新的机遇&#xff0c;也对企业提出了更高的要求。企业需要借助科技的力量&#xff0c;实现数字化、智能化、高效化的转型&#xff0c;以应对激烈的市场竞争。 湖南远跃作为国内领先的信息一体化 解决方…

【Linux】进程的基本属性|父子进程关系

个人主页&#xff1a;&#x1f35d;在肯德基吃麻辣烫 我的gitee&#xff1a;Linux仓库 个人专栏&#xff1a;Linux专栏 分享一句喜欢的话&#xff1a;热烈的火焰&#xff0c;冰封在最沉默的火山深处 文章目录 前言进程属性1.进程PID和PPID2.fork函数创建子进程1&#xff09;为什…

炫酷UI前端效果的CSS生成工具

提升设计人员和前端开发人员的工作 推荐炫酷UI前端效果的CSS生成工具1.Neumorphism2.带有渐变的图标3.Interactions4.大型数据库5.动画6.Mask7.动画按钮8. 自定义形状分隔线9.背景图案10. SVG波浪推荐炫酷UI前端效果的CSS生成工具 1.Neumorphism 地址:https://neumorphism.i…

Python案例|Pandas正则表达式

字符串的处理在数据清洗中占比很大。也就是说,很多不规则的数据处理都是在对字符串进行处理。Excel提供了拆分、提取、查找和替换等对字符串处理的技术。在Pandas中同样提供了这些功能,并且在Pandas中还有正则表达式技术的加持,让其字符串处理能力更加强大。 01、正则 正则就是…

爆肝整理,pytest自动化测试框架-常用插件整理(必知必会)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Pytest拥有丰富的…

VS2019 + Qt : setToolTip的提示内容出现乱码

VS2019 Qt : setToolTip的提示内容出现乱码 在使用setToolTip()时&#xff0c; setToolTip(QString("asd你好&#xff01;");标签提示只有英文是对的&#xff0c;中文是乱码&#xff01; 应该是编码出了问题。默认情况下&#xff0c;Qt使用的是UTF-8编码&#xf…

【Apollo】推动创新:探索阿波罗自动驾驶的进步(含安装 Apollo的详细教程)

前言 Apollo (阿波罗)是一个开放的、完整的、安全的平台&#xff0c;将帮助汽车行业及自动驾驶领域的合作伙伴结合车辆和硬件系统&#xff0c;快速搭建一套属于自己的自动驾驶系统。 开放能力、共享资源、加速创新、持续共赢是 Apollo 开放平台的口号。百度把自己所拥有的强大、…