【代码随想录训练营第42期 Day57打卡 - 图论Part7 - Prim算法

一、Prim算法

Prim算法是一种贪心算法,用于求解加权无向图的最小生成树问题。其中,最小生成树是指一个边的子集,它连接图中的所有顶点,且边的总权重最小,并且没有形成环。

对于Prim算法的简单了解,这里推荐看看:【图-最小生成树-Prim(普里姆)算法和Kruskal(克鲁斯卡尔)算法】

二、题目与题解

题目:卡码网 53. 寻宝

题目链接

53. 寻宝(第七期模拟笔试) (kamacoder.com)

题目描述

在世界的某个区域,有一些分散的神秘岛屿,每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这些岛屿上建公路,方便运输。

不同岛屿之间,路途距离不同,国王希望你可以规划建公路的方案,如何可以以最短的总公路距离将 所有岛屿联通起来(注意:这是一个无向图)。 

给定一张地图,其中包括了所有的岛屿,以及它们之间的距离。以最小化公路建设长度,确保可以链接到所有岛屿。

输入描述

第一行包含两个整数V 和 E,V代表顶点数,E代表边数 。顶点编号是从1到V。例如:V=2,一个有两个顶点,分别是1和2。

接下来共有 E 行,每行三个整数 v1,v2 和 val,v1 和 v2 为边的起点和终点,val代表边的权值。

输出描述

输出联通所有岛屿的最小路径总距离

输入示例

7 11
1 2 1
1 3 1
1 5 2
2 6 1
2 4 2
2 3 2
3 4 1
4 5 1
5 6 2
5 7 1
6 7 1

输出示例

6

提示信息

数据范围:
2 <= V <= 10000;
1 <= E <= 100000;
0 <= val <= 10000;

如下图,可见将所有的顶点都访问一遍,总距离最低是6.

  

题解:Prim算法

建议先看视频了解了Prim算法的实现步骤再看以下思路和步骤。

基本思路:

1.选择一个起始顶点,将其标记为已访问,并将其距离设置为0,其他顶点的距离设置为无穷大

2.创建一个循环,直到所有顶点都被访问:

        初始化一个变量来记录当前最小边的权重,将其设置为无穷大。

        初始化两个变量来记录最小边的两个顶点。

3.遍历所有已访问顶点,对于每个已访问顶点,遍历它的所有邻接顶点:

        如果邻接顶点未被访问,并且连接这两个顶点的边的权重小于当前记录的最小边权重,则更新最小边权重和对应的两个顶点。

        将找到的最小边加入到最小生成树中,并标记连接的非最小生成树顶点为已访问。 更新该顶点的所有邻接顶点到最小生成树的最短距离。

4.当所有顶点都被访问后,算法结束,此时最小生成树由记录的所有边组成。

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int v, e;
    int x, y, k;
    cin >> v >> e;                                              // 输入顶点数v(注意范围是:1 - v)和边数e
    vector<vector<int>> grid(v + 1, vector<int>(v + 1, 10001)); // 二维数组grid,用于存储图的邻接矩阵,初始值为10001(表示无穷大)
    while (e--)
    {
        cin >> x >> y >> k; // 输入边的两个顶点和权值
        // 因为是双向图,所以两个方向都要填上
        grid[x][y] = k;
        grid[y][x] = k;
    }
    // 用于存储每个顶点到最小生成树的最短距离 -- 由于顶点数为v,这里大小设置为v+1
    vector<int> minDist(v + 1, 10001);
    // 初始化第一个顶点到最小生成树的距离为0
    minDist[1] = 0;

    // 用于标记顶点是否已经在最小生成树中
    vector<bool> isInTree(v + 1, false);

    // 我们只需要循环 n-1次,因为最小生成树有v-1条边,这样就可以把n个节点的图连在一起
    for (int i = 1; i < v; i++)
    {
        // 选择距离最小生成树最近的顶点
        int cur = -1;                // 当前选中的顶点 -- 最终选中的cur节点即是加入最小生成树的最近节点
        int minVal = INT_MAX;        // 当前最小距离,初始化为无穷大
        for (int j = 1; j <= v; j++) // 顶点编号:1 - v
        {
            if (!isInTree[j] && minDist[j] < minVal) // 选择不在最小生成树中且距离最小的顶点
            {
                minVal = minDist[j];
                cur = j;
            }
        }
        // 最近节点(cur)加入生成树
        isInTree[cur] = true;

        // 更新非生成树节点到生成树的距离(即更新minDist数组):由于新加入了cur节点,这里只需要多考虑cur与不在最小生成树的节点的距离即可
        for (int j = 1; j <= v; j++)
        {
            if (!isInTree[j] && grid[cur][j] < minDist[j]) // 如果顶点j不在生成树中,并且通过cur到j的距离小于当前记录的最短距离,则更新
            {
                minDist[j] = grid[cur][j];
            }
        }
    }
    int ans = 0;                 // 统计结果
    for (int i = 2; i <= v; i++) // 累加每个顶点到生成树的最短距离,注意从第二个顶点开始累加,因为第一个顶点距离为0
    {
        ans += minDist[i];
    }
    cout << ans << endl;
}

这题还可以用优先队列(堆)进行优化,这也是Prim算法最经典的使用方法:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int v, e;
    cin >> v >> e; // 输入顶点数v和边数e

    // 使用邻接矩阵存储图的边信息,初始化为无穷大
    vector<vector<int>> grid(v + 1, vector<int>(v + 1, INT_MAX));

    // 读取边的信息
    for (int i = 1; i <= e; ++i)
    {
        int x, y, k;
        cin >> x >> y >> k; // 输入边的两个顶点和权值
        grid[x][y] = k;
        grid[y][x] = k;
    }

    // 使用优先队列来存储顶点及其到最小生成树的最短距离
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

    // 用于存储每个顶点到最小生成树的最短距离,初始化为无穷大
    vector<int> minDist(v + 1, INT_MAX);
    minDist[1] = 0; // 第一个顶点到最小生成树的距离为0

    // 标记顶点是否已经在最小生成树中
    vector<bool> isInTree(v + 1, false);

    // 将第一个顶点加入优先队列
    pq.push({0, 1});

    while (!pq.empty())
    {
        // 从优先队列中取出距离最小生成树最近的顶点
        int cur = pq.top().second;
        pq.pop();

        // 如果该顶点已经在最小生成树中,则跳过
        if (isInTree[cur])
            continue;

        // 将该顶点标记为已加入最小生成树
        isInTree[cur] = true;

        // 更新邻接顶点到最小生成树的最短距离
        for (int j = 1; j <= v; ++j)
        {
            if (!isInTree[j] && grid[cur][j] < minDist[j])
            {
                minDist[j] = grid[cur][j];
                pq.push({minDist[j], j}); // 将更新后的顶点和距离加入优先队列
            }
        }
    }

    // 计算最小生成树的总权重
    int ans = 0;
    for (int i = 2; i <= v; ++i)
    {
        ans += minDist[i];
    }

    cout << ans << endl; // 输出最小生成树的总权重
    return 0;
}

 三、小结

今天的打卡比较仓促,后边有时间会对上述代码的内容以及注释进行改善,并加深自己的理解。后边继续加油!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于小程序的教学辅助微信小程序设计+ssm(lw+演示+源码+运行)

教学辅助微信小程序 摘 要 随着移动应用技术的发展&#xff0c;越来越多的学生借助于移动手机、电脑完成生活中的事务&#xff0c;许多的传统行业也更加重视与互联网的结合&#xff0c;由于学生学习的压力越来越大&#xff0c;教学辅助是一个非常不错的教育平台&#xff0c;对…

9.12-kubeadm方式安装k8s+基础命令的使用

一、安装环境 编号主机名称ip地址1k8s-master192.168.2.662k8s-node01192.168.2.773k8s-node02192.168.2.88 二、前期准备 1.设置免密登录 [rootk8s-master ~]# ssh-keygen[rootk8s-master ~]# ssh-copy-id root192.168.2.77[rootk8s-master ~]# ssh-copy-id root192.168.2.…

指令——计算机的语言(part 2)

目录 1.1 翻译并执行程序 1.1.1 编译器 1.1.2 汇编器 1.1.3 链接器 1.1.4 加载器 1.1.5 动态链接库 接上一篇文章: 指令——计算机的语言(part 1) 1.1 翻译并执行程序 程序翻译层次图如下: 首先高级语言比如说C&#xff0c;会被编译器编译成汇编语言&#xff0c;然后汇…

Python面试宝典第48题:找丑数

题目 我们把只包含质因子2、3和5的数称作丑数&#xff08;Ugly Number&#xff09;。比如&#xff1a;6、8都是丑数&#xff0c;但14不是&#xff0c;因为它包含质因子7。习惯上&#xff0c;我们把1当做是第一个丑数。求按从小到大的顺序的第n个丑数。 示例 1&#xff1a; 输入…

另类动态规划

前言&#xff1a;一开始我根本想不到这个题目是一个动态规划的题目&#xff0c;而且我一开始的初始状态还写错了 我还忘记了写算法题的基本步骤&#xff0c;先看数据范围&#xff0c;再考虑能不能用动态规划写 题目地址 #include <bits/stdc.h> using namespace std; #de…

3C电子胶黏剂在手机制造方面有哪些关键的应用

3C电子胶黏剂在手机制造方面有哪些关键的应用 3C电子胶黏剂在手机制造中扮演着至关重要的角色&#xff0c;其应用广泛且细致&#xff0c;覆盖了手机内部组件的多个层面&#xff0c;确保了设备的可靠性和性能。以下是电子胶在手机制造中的关键应用&#xff1a; 手机主板用胶&…

浏览器百科:网页存储篇-IndexedDB介绍(十)

1.引言 在现代网页开发中&#xff0c;数据存储需求日益增多和复杂&#xff0c;传统的客户端存储技术如localStorage和sessionStorage已难以满足大型数据的存储和管理需求。为了解决这一问题&#xff0c;HTML5 引入了 IndexedDB&#xff0c;在本篇《浏览器百科&#xff1a;网页…

网络学习-eNSP配置路由器

#PC1网关&#xff1a;192.168.1.254 #PC3网关&#xff1a;192.168.3.254 #PC4网关&#xff1a;192.168.4.254# 注&#xff1a;路由器接口必须配置不同网段IP地址 <Huawei>system-view Enter system view, return user view with CtrlZ. #给路由器两个接口配置IP地址 [Hua…

IBM中国研发中心撤出:挑战与机遇并存

IBM中国研发中心撤出&#xff1a;挑战与机遇并存 引言 近日&#xff0c;IBM宣布撤出在中国的两大研发中心的消息&#xff0c;引起了广泛关注。这一举动不仅对IBM自身的全球布局产生了影响&#xff0c;也在一定程度上反映了跨国公司在中国市场策略的调整。本文将探讨这一事件背…

keras和tensorflow可用的一组版本

目录 keras版本&#xff1a;3.5.0tensorflow&#xff1a;2.17.0之前的错误导包现在的正确导包 keras版本&#xff1a;3.5.0 tensorflow&#xff1a;2.17.0 之前的错误导包 其实也不是说错误&#xff0c;就是因为文件位置不对&#xff0c;所以VSCode总是有黄色波浪线&#xff0…

只出现一次的数II

只出现一次的数&#xff1a;力扣&#xff08;LeetCode&#xff09;-----只出现一次的数 题目描述 给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 示例 1&#xff1a; 输入&am…

C# WinForm:禁用Panel容器滚动条自动移动位置的功能

1.在WinForm项目中新建一个类&#xff1a; 2.类里面的内容&#xff0c;重写Panel的这个方法 3.编译后这个控件就出现在工具箱了 4.然后用这个新Panel控件就好了 5.完事大吉。

Datasheet SHT20芯片的数据手册

Datasheet SHT20芯片的数据手册 I2C读取湿度传感器返回的16位数据。SCL SDA 14位有效&#xff0c;我以为是将后二位删除&#xff0c;实际上看完手册才知道是后二位值无用&#xff0c;不是删除&#xff0c;而是清0&#xff0c;实际上还是16为&#xff0c;知识后二位是0还是1&…

深度学习——基础知识

深度学习的重点在于优化&#xff0c;其中很重要的步骤在于如何调参&#xff0c;会涉及到一些微积分等数学知识。不同于以往接触到的数值运算&#xff0c;深度&#xff08;机器&#xff09;学习都是关于张量Tensor&#xff08;向量&#xff09;的计算&#xff0c;Python中最常用…

leetcode21. 合并两个有序链表

思路&#xff1a; 用一个新链表来表示合并后的有序链表&#xff0c; 每次比较两个链表&#xff0c;将较小的那个结点存储至新链表中 # Definition for singly-linked list. # class ListNode(object): # def __init__(self, val0, nextNone): # self.val val # …

机器学习(西瓜书)第 9 章 聚类

9.1 聚类任务和距离计算 在”无监督学习“中&#xff0c;训练样本的标记信息是未知的&#xff0c;目标是通过对无标记训练样本的学习来揭示数据的内在性质及规律&#xff0c;为进一步的数据分析提供基础.此类学习任务中研究最多、应用最广的是“聚类”(clustering). 聚类试图…

动手学深度学习(pytorch)学习记录30-含并行连接的网络(GoogLeNet)[学习记录]

目录 GoogLeNetInception块GoogLeNet模型训练模型 GoogLeNet GoogLeNet&#xff0c;也称为Inception v1&#xff0c;是由Google团队在2014年提出的深度学习模型&#xff0c;它在当年的ImageNet竞赛中取得了显著的成绩。GoogLeNet的设计引入了多个创新点&#xff0c;包括Incept…

【C++】string类的基本使用

一、string类的由来 在C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列 的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&#xff0c;而且底层空间需要用户 自己管…

大数据之Flink(三)

9.3、转换算子 9.3.1、基本转换算子 9.3.1.1、映射map 一一映射 package transform;import bean.WaterSensor; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; impor…

分类预测|基于改进的灰狼IGWO优化支持向量机SVM的数据分类预测matlab程序 改进策略:Cat混沌与高斯变异

分类预测|基于改进的灰狼IGWO优化支持向量机SVM的数据分类预测matlab程序 改进策略&#xff1a;Cat混沌与高斯变异 文章目录 一、基本原理原理流程1. **定义目标函数**2. **初始化GWO**3. **评估适应度**4. **更新狼的位置**5. **更新狼的等级**6. **重复迭代**7. **选择最佳解…