图论-最小生成树

news2024/9/20 10:58:26

Prim算法


算法描述

dist[i]<--\infty

for(i =0;i<n;i++)

t<--找到集合外最近的点

用t更新其他点到集合的距离(这个集合就是已经确定的最小生成树的点和边)

st[t] = true;

  1. dist[i] <-- 无穷

    这一步是初始化所有节点到集合的最小距离为无穷大。dist[i] 表示从已选节点集合到节点 i 的最小边权值。在算法开始时,所有的节点距离都是无穷大,因为还没有选择任何节点。

    for (i = 0; i < n; i++) {
        dist[i] = INF; // INF 代表无穷大
    }
    
  2. for (i = 0; i < n; i++)

    这是一个循环,用来初始化每个节点的距离。通常情况下,这里的 n 是图中节点的数量。在 Prim 算法中,我们会从集合中逐步选出节点,因此一开始要设置所有节点的距离。

    for (i = 0; i < n; i++) {
        // 初始化 dist 数组
    }
    
  3. t <-- 找到集合外最近的点

    这一部分是 Prim 算法的核心。t 是当前最小生成树(MST)中包含的节点集合之外的节点中,距离集合最近的节点。这个节点 t 是当前最小边权值的节点,且这个节点在生成树中尚未包含。

    int t = -1;
    for (i = 0; i < n; i++) {
        if (!st[i] && (t == -1 || dist[i] < dist[t])) {
            t = i;
        }
    }
    

    在这个代码片段中,st 是一个布尔数组,用来表示节点是否已被加入到生成树中。dist[i] 是节点 i 到生成树中节点的最小距离。

  4. 用 t 更新其他点到集合的距离

    一旦找到 t,你需要更新所有与 t 相连的、尚未被包含在生成树中的节点的距离。如果通过 t 到某个节点 v 的边权值更小,就更新 dist[v]

    for (每个与 t 相连的节点 v) {
        if (!st[v] && edge(t, v) < dist[v]) {
            dist[v] = edge(t, v);
        }
    }
    

    这里 edge(t, v) 表示从节点 t 到节点 v 的边的权值。

  5. st[t] = true

    最后,将 t 标记为已经包含在生成树中。这表示节点 t 现在是最小生成树的一部分,不再需要考虑 t 的边来更新其他节点的距离。

    st[t] = true;
    

    这里 st 是一个布尔数组,st[i] 为 true 表示节点 i 已经被包含在生成树中。

图例

已知有下面树:
 

第一步:初始化,将所有点距离集合的距离设置为无穷,此时所有点都没有加入集合。
 

将节点1加入集合(此时所有点距离集合都是inf,所以可以随便找到一个点

根据节点1更新其他点到集合的最小距离,暂时将2、3、4更新为(1)(2)(3)。

然后将节点1放入集合

再找到集合外最近的点2号点。

根据2号点更新其他不在集合的点的距离,此时没有借助2号点能变得更小的,因此不变。

将2号点放入集合中。

再次找到不在集合中的最小的点,即3号点。

根据3号点更新距离,没有改变

将3号点放入集合

继续找4号点,也没有更新距离。

算法结束。

例题


858. Prim算法求最小生成树 - AcWing题库

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N =510,INF=100000000;
int g[N][N],dist[N];
bool st[N];
int n,m;

int prim(){
    fill(dist,dist+N,INF);
    int res=0;
    dist[1] = 0;//把第一个点设置为0方便后面操作。
    for(int i=0;i<n;i++){
        int t=-1;
        for(int j=1;j<=n;j++)
        {
            if(!st[j] && (t ==-1 || dist[t] > dist[j]))
            {//注意,这里是比较dist[t] > dist[j],在st==false的点中找到一个最小的
                t = j;
            }
        }
        if(dist[t]==INF){
            return INF;
        }//不是第一次轮回的,一定有一个最小的点,如果没有说明不连通。
        
        res += dist[t];//这两步一定要在前面,因为这是将t放入集合,后面才不会再次更新t了
        st[t] = true;
        
        //根据节点t更新其他距离。
        for(int j=1;j<=n;j++){
            if(!st[j]){
                dist[j] = min(dist[j],g[t][j]);//这里省去了判断两个点是否有边,即使没有边也是INF
            }
        }
        

    }
    return res;
    
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            g[i][j] = INF;
        }
    }
    for(int i=0;i<m;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        g[a][b] = g[b][a] = min(c,g[a][b]);//一定要注意只存储最小边。
    }
    for(int i=1;i<=n;i++) g[i][i] = 0;//解决自环问题
    int ans = prim();
    if(ans == INF) printf("impossible");
    else printf("%d",ans);
    
    return 0;
}

Kruskal算法

算法描述:

将每一条边按照权重从小到大排序

枚举每一条边a,b权重是c

如何a、b所在集合不连通,将a-b加入到集合中去。

这里判断a、b是否在同意集合需要用并查集来解决。

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5+10,M=2*N;
int res,p[N],n,m,st[N],cnt;
struct E{
    int a,b,w;
    bool operator<(const E &e){
        return this->w<e.w;
    }
}Edges[M];//注意存储的是边

int myfind(int x){
    if(x!=p[x]) p[x] = myfind(p[x]);
    return p[x];
}

int krus(){
    for(int i=1;i<=m;i++){
        
        E e = Edges[i];
        int sa = myfind(e.a);
        int sb = myfind(e.b);
        if(sa != sb){
            res+=e.w;
            p[sb] = sa;
            cnt++;
        }
    }
    if(cnt<n-1) return 0;
    return res;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        p[i] = i;
    }
    for(int i=1;i<=m;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        Edges[i].a=a;
        Edges[i].b=b;
        Edges[i].w=c;
    }
    sort(Edges+1,Edges+m+1);
    int tag = krus();
    if(tag==0) cout<<"impossible";
    else{
        cout<<tag;
    }
    
    return 0;
}

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

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

相关文章

科普文:微服务之Spring Cloud 服务调用组件Openfeign

一、概述 Feign是声明式Web服务客户端&#xff0c;它使编写Web服务客户端更加容易。 Feign不做任何请求处理&#xff0c;通过处理注解相关信息生成Request&#xff0c;并对调用返回的数据进行解码&#xff0c;从而实现简化HTTP API的开发。 如果要使用Feign&#xff0c;需要创…

项目相关内容 ----- 2实现打印 ---- 图片与字符

目录 1 . 实现图图片的打印 1&#xff09;结构体定义 2&#xff09;画点线 3&#xff09;清屏 4&#xff09;图片显示 5&#xff09;主函数部分 2 . 实现字符的打印 1) 定义BMP位图文件的头部信息以及信息头​ 2&#xff09;实现打印字符的绘制​ 3 . 打印文本内容​ 附…

你会在Vision Pro里编程吗?

你会在Vision Pro里编程吗&#xff1f; Vision Pro作为一位开发者&#xff0c;你会考虑将Vision Pro应用到编程中吗&#xff1f;你认为Vision Pro有可能改变开发者的工作模式与效率吗&#xff1f; 初见Vision Pro有点陌生&#xff0c;不太了解Vision Pro是什么。那么这里先来了…

顶点着色器片段着色器

/* * FileName : OpenGL_Tutorial.cpp * Time : 2024-08-03 10:00:00 * Author : XuMing * Email : 920972751qq.com * description : 使用OpenGL进行顶点输入和着色器编译的详细解析 */#include <glad/glad.h> #include <GLFW/glfw3.…

【论文阅读visual grounding】QRNet论文解读与关键代码实现

Shifting More Attention to Visual Backbone: Query-modulated Refinement Networks for End-to-End Visual Grounding 论文链接&#xff1a;https://arxiv.org/abs/2203.15442 代码链接&#xff1a;https://github.com/z-w-wang/QRNet Motivation 视觉定位&#xff08;visua…

JavaScript基础——JavaScript变量声明

变量是存储数据的容器&#xff0c;可以变的量&#xff0c;值可以改变&#xff0c;在JavaScript中&#xff0c;变量声明的关键字有var、let&#xff0c;其中&#xff0c;var是ES5的语法&#xff0c;let是ES6的语法&#xff0c;变量需要先声明&#xff0c;在使用。 声明一个age变…

整除分块, CF538 F - A Heap of Heaps

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 F - A Heap of Heaps 二、解题报告 1、思路分析 给定v&#xff0c;k&#xff0c;v的父节点p (v - 2) / k 1 我们令P p - 1&#xff0c;V V - 2 P V / k&#xff0c;我们发现这就是一个整除分块问题…

Ubuntu22.04之有道词典mini窗口无法拖动问题(二百六十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…

混合域注意力机制(空间+通道)

在计算机视觉任务中&#xff0c;空间域注意力通常关注图像中不同位置的重要性&#xff0c;例如突出图像中的关键对象或区域。而通道域注意力则侧重于不同通道&#xff08;特征图&#xff09;的重要性&#xff0c;决定哪些特征对于任务更具判别力。混合域注意力机制结合了空间域…

FIR低通滤波器

FIR低通滤波器 FIR(Finite Impulse Response)滤波器:有限长单位冲激响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。 MATLAB实现…

详细了解架构师

架构师的核心职责是消除不确定性和降低复杂性&#xff01; 架构师画像 架构师的定位 架构设计环 澄清和技术相关的&#xff0c;比如支持百万级别的&#xff0c;架构师需要澄清&#xff0c;可能只有十万级。 架构师的三个核心能力 架构师的三个关键思维 架构设计流程和架构师…

初识MQ——学习MQ之前需要了解的知识点

目录 前言 1. 同步和异步通讯 1.1 同步通讯 1.2 异步通讯 2. MQ技术对比 前言 在现在的大数据时代&#xff0c;高并发的情况越来越普遍&#xff0c;系统一个不注意&#xff0c;就可能崩溃无法访问了。这是开发最不想看到的情况&#xff0c;如果是上班还好&#xff0c;可以…

【C++】—— 类与对象(二)

【C】—— 类与对象&#xff08;二&#xff09; 1、类的默认成员函数2、构造函数2.1、初见构造2.2、深入构造2.3、初始化列表2.3.1、什么是初始化列表2.3.2、初始化列表和函数体关系2.3.3、必须使用初始化列表的情况2.3.3.1、 c o n s t const const 成员变量2.3.3.2、引用成员…

AS400==tutorial for Beginners

系统AS400 语言RPGLE 参考视频&#xff1a; https://www.youtube.com/watch?vFqgwYsp7mjk&listPL3W4xRdnQJHVWWmYX1Klji7QUk_PQhq0t&index5 Lesson 1 | Introduction to As-400 and setting up As-400 Environment. 客户端软件TN5250 Terminal Emulation for Window…

MyBatis全方位指南:从注解到XML文件的数据库操作

目录 一.什么是MyBatis 入门程序初体验 二.MyBatis基本操作CRUD ▐ 增(Insert) 返回主键 ▐ 删(Delete) ▐ 改(Update) ▐ 查(Select) 起别名 结果映射 开启驼峰命名(推荐) 三.MyBatis XML配置文件 ▐ 增(Insert) ▐ 删(Delete) ▐ 改(Update) ▐ 查(Select) …

PostgreSQL(二十三)TOAST技术

目录 一、TOAST简介 二、TOAST的存储方式 1、存储方式概述 2、实验&#xff1a;创建TOAST表 三、TOAST的4种压缩策略 1、策略说明 2、TOAST表额外的三个字段 四、TOAST表的计算方式 1、说明 2、实验&#xff1a;计算表大小 五、TOAST表的特点 1、优点 2、缺点 3、…

【KAN】【API教程】get_fun

抽取某个激活函数的样子 from kan import * import matplotlib.pyplot as plt # create a KAN: 2D inputs, 1D output, and 5 hidden neurons. cubic spline (k3), 5 grid intervals (grid5). model KAN(width[2,5,1], grid5, k3, seed0) x torch.normal(0,1,size(100,2)) m…

给虚拟机Ubuntu扩展硬盘且不丢数据

1.Ubuntu关机状态下先扩展&#xff0c;如扩展20GB 2.进入ubuntu&#xff0c;切换root登录&#xff0c;必须是root全选&#xff0c;否则启动不了分区工具gparted 将新的20GB创建好后&#xff0c;选择ext4,primary&#xff1b; 3.永久挂载 我的主目录在/并挂载到/dev/sda1 从图…

C++解决:早餐组合

前言 应该都知道我之前沉默了很长一段时间&#xff0c;现在慢慢想明白了&#xff0c;会继续创作&#xff0c;真的非常感谢大家对我这个幼稚小孩的支持与鼓励。 有朋友私信问我退的原因&#xff0c;在这里和大家简要说一下【狗头】 我认识一位开学初三的学长&#xff0c;他和…

H81002S 1.7mm网络变压器:BMS汽车蓝牙接收器中的超薄共模电感科技

华强盛导读&#xff1a;在当今这个日新月异的汽车科技领域&#xff0c;每一处细节都蕴含着创新与突破。作为电动汽车心脏的电池管理系统&#xff08;BMS&#xff09;&#xff0c;其高效稳定的运行不仅关乎续航与安全&#xff0c;更是智能化驾驶体验的基石。而在这背后&#xff…