最小生成树算法

news2025/9/20 17:22:14

文章目录



最小生成树概述

概述


P r i m Prim Prim 算法 - 稠密图 - O ( n 2 ) O(n^2) O(n2)

思路概述

D i j k s t r a Dijkstra Dijkstra 算法很相近,都是每个点轮一遍然后贪心找最小值,同样, P r i m Prim Prim 也可以用堆优化,但是不如 K r u s k a l Kruskal Kruskal 算法,所以不用。

  • 用到三个数组:g[][]邻接矩阵存边,st[]用于标记那些节点在生成树中,dist[]存储每个节点到生成树的最小距离。
  • 首先,初始化每个点到生成树的距离,在一开始,除了根节点是 0 0 0,其他都是 I N F INF INF;
  • 然后每个点轮一遍(因为生成树要每个点都在)
    • 再次遍历,寻找到生成树最小的边连接的点,如果遍历完了发现最小值是 I N F INF INF,说明这个图不联通,没有最小生成树。
    • 将这个点更新到生成树里去,累计生成树的边长,然后用这个点的值再更新一遍dist[]数组。

时间复杂度分析

外层循环 n n n 次,内层是 2 n 2n 2n 次,所以是 O ( n ⋅ 2 n ) O(n·2n) O(n2n),也就是 O ( n 2 ) O(n^2) O(n2)


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

题目链接:https://www.acwing.com/activity/content/problem/content/924/。

最小生成树

CODE
#include <iostream>  // 引入输入输出流库
#include <cstring>   // 引入字符串处理库
#include <algorithm> // 引入算法库

using namespace std; // 使用标准命名空间

const int N = 520, INF = 0x3f3f3f3f; // 定义常量N和INF
int g[N][N]; // 定义邻接矩阵g
int dist[N]; // 定义距离数组dist
bool st[N];  // 定义状态数组st
int n, m;    // 定义顶点数n和边数m

int prim(){  	// 定义prim算法函数
    memset(dist, 0x3f, sizeof dist); 	// 初始化dist数组
    dist[1] = 0; 	// 将起点的距离设为0
    
    int res = 0; 	// 初始化结果res
    for(int i = 0; i < n; ++i){ 	// 遍历所有顶点
        int t = -1; 	// 初始化t
        
        for(int j = 1; j <= n; ++j) 	// 遍历所有顶点
            if(!st[j] && (t == -1 || dist[t] > dist[j])) // 找到未被访问且距离最小的顶点
                t = j;
        
        if(dist[t] == INF) return INF; 	// 如果找不到顶点,返回INF
        
        res += dist[t]; 	// 更新结果
        st[t] = true; 		// 标记顶点t已被访问
        
        for(int j = 1; j <= n; ++j) dist[j] = min(dist[j], g[j][t]); 	// 更新距离
    }

    return res; 	// 返回结果
}

int main() 		// 主函数
{
    memset(g, 0x3f, sizeof g); 	// 初始化邻接矩阵g
    
    cin >> n >> m; 		// 输入顶点数和边数
    
    while (m -- ){ 		// 遍历所有边
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c); 	// 输入边的两个顶点和权值
        
        g[a][b] = g[b][a] = min(g[a][b], c); // 更新邻接矩阵
    }
    
    int t = prim(); 	// 调用prim算法
    
    if(t == INF) puts("impossible"); 	// 如果返回INF,输出"impossible"
    else printf("%d\n", t); 			// 否则输出结果
}



K r u s k a l Kruskal Kruskal 算法 - 稀疏图 - O ( m l o g m ) O(mlogm) O(mlogm)

思路解析

  • 首先,将所有边按权值排序,这一步是 K r u s k a l Kruskal Kruskal 的瓶颈,复杂度是 O ( m ⋅ l o g m ) O(m·logm) O(mlogm)
  • 接着初始化并查集,再把排序好的边轮一遍。
    • 如果边的两个点的根节点不是同一个(两个节点没有全在树中),那就将两个点连起来,然后节点数和权重累积。
  • 最后判断,如果生成树的边不是 n − 1 n - 1 n1 条的话,说明图不联通,没有最小生成树。

时间复杂度分析

由上知排序瓶颈复杂度,然后是后面遍历每一条边的复杂度 O ( m ) O(m) O(m),最后累计就是 O ( m l o g m ) O(mlogm) O(mlogm)
但是由于排序的常数很小,所以实际运行时间比公式算出来要少的多。


AcWing 859. Kruskal算法求最小生成树

题目链接:https://www.acwing.com/activity/content/problem/content/925/

kruskal

CODE
#include <iostream>  // 引入输入输出流库
#include <cstring>   // 引入字符串处理库
#include <algorithm> // 引入算法库

using namespace std; // 使用标准命名空间

const int N = 1e5 + 10, M = 2e5 + 10, INF = 0x3f3f3f3f; 	// 定义常量N、M和INF
int n, m; 	// 定义顶点数n和边数m
int p[N]; 	// 定义并查集数组p

struct edge{ 	// 定义边的结构体
    int a, b, w;
}edges[M];

int find(int x){ 	// 定义并查集的查找函数
    if(x != p[x]) p[x] = find(p[x]);
    return p[x];
}

bool cmp(edge a, edge b){ 	// 定义比较函数,用于排序
    return a.w < b.w;
}

int kruskal(){ // 定义kruskal算法函数
    sort(edges, edges + m, cmp); 	// 对所有边按权值进行排序
    
    for(int i = 1; i <= n; ++i) p[i] = i; 	// 初始化并查集
    
    int res = 0, cnt = 0; 	// 初始化结果res和计数器cnt
    for(int i = 0; i < m; ++i){ 	// 遍历所有边
        int a = find(edges[i].a), b = find(edges[i].b), w = edges[i].w; 
        // 找到边的两个顶点的根节点和权值
        
        if(a != b){ 	// 如果两个顶点不在同一个集合中
            p[a] = b; 	// 合并两个集合
            cnt++; 		// 计数器加1
            res += w; 	// 更新结果
        }
    }
    
    if(cnt < n - 1) return INF; 	// 如果生成树的边数小于n-1,返回INF
    else return res; 	// 否则返回结果
}

int main() // 主函数
{
    cin >> n >> m; 	// 输入顶点数和边数
    
    for(int i = 0; i < m; ++i){ 	// 遍历所有边
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w); 	// 输入边的两个顶点和权值
        
        edges[i] = {a, b, w}; 	// 存储边
    }
    
    int t = kruskal(); 	// 调用kruskal算法
    
    if(t == INF) puts("impossible"); 	// 如果返回INF,输出"impossible"
    else printf("%d\n", t); 	// 否则输出结果
}

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

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

相关文章

Java数据结构之《哈希查找》题目

一、前言&#xff1a; 这是怀化学院的&#xff1a;Java数据结构中的一道难度中等的一道编程题(此方法为博主自己研究&#xff0c;问题基本解决&#xff0c;若有bug欢迎下方评论提出意见&#xff0c;我会第一时间改进代码&#xff0c;谢谢&#xff01;) 后面其他编程题只要我写完…

7.C转python

1.对字典的各种操作都是对键来进行的 2.关于字典的遍历操作 例: 还可以这样遍历 所以生成了一个固定模版来遍历字典: 例: 那两个名字可以换 例: 3.合法key的类型: 要求可哈希 在python中,专门提供了一个hash()函数来计算哈希值 例: 有的类型是不能计算哈希的,如:列表,字…

YOLOv8界面-目标检测+语义分割+追踪+姿态识别(姿态估计)+界面DeepSort/ByteTrack-PyQt-GUI

YOLOv8-DeepSort/ByteTrack-PyQt-GUI&#xff1a;全面解决方案&#xff0c;涵盖目标检测、跟踪和人体姿态估计 YOLOv8-DeepSort/ByteTrack-PyQt-GUI是一个多功能图形用户界面&#xff0c;旨在充分发挥YOLOv8在目标检测/跟踪和人体姿态估计/跟踪方面的能力&#xff0c;与图像、…

腾讯云云服务器功能与优势

腾讯云云服务器&#xff08;Cloud Virtual Machine&#xff0c;CVM&#xff09;是腾讯云提供的可扩展的计算服务。使用云服务器 CVM 避免了使用传统服务器时需要预估资源用量及前期投入的问题&#xff0c;帮助您在短时间内快速启动任意数量的云服务器并及时部署应用程序。 云服…

在 AlmaLinux9 上安装Oracle Database 23c

在 AlmaLinux9 上安装Oracle Database 23c 0. 下载 Oracle Database 23c 安装文件1. 安装 Oracle Database 23c3. 连接 Oracle Database 23c4. &#xff08;谨慎&#xff09;卸载 Oracle Database 23c 0. 下载 Oracle Database 23c 安装文件 版权问题&#xff0c;下载地址请等待…

ASP.NET版本WOL服务的使用

本文以WOL为例&#xff0c;演示如何通过 GPT-4 让其为 WebAPI 项目设计一个网页。其中介绍了如何让GPT4生成相关功能&#xff0c;添加动画效果&#xff0c;接口鉴权等。 1. 背景 前面我们已经完成了一个WOL服务的开发&#xff0c;并将其迁移改造为了 ASP.NET 服务并完成了部署…

电脑提示mfc100u.dll缺失如何解决?分享有效的5个解决方法

由于各种原因&#xff0c;电脑可能会出现一些问题&#xff0c;其中之一就是电脑提示mfc100u.dll的错误。这个问题可能会导致电脑无法正常运行某些程序或功能。为了解决这个问题&#xff0c;我将分享验证有效的五个修复方法&#xff0c;帮助大家恢复电脑的正常运行。 首先&#…

【spring(六)】WebSocket网络传输协议

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 核心概要&#xff1a; 概念介绍&#xff1a; 对比HTTP协议&#xff1a;⭐ WebSocket入门案例&#xff1a;⭐ 核心概要&#xff1a; websocket对比http 概念介绍&#xff1a; WebSocket是Web服务器的一个组件…

一、服务器准备

本案例使用VMware Workstation Pro虚拟机创建虚拟服务器来搭建Linux服务器集群&#xff0c;所用软件及版本如下&#xff1a; Centos7.7-64bit 1、三台虚拟机创建 第一种方式&#xff1a;通过iso镜像文件来进行安装(不推荐) 第二种方式&#xff1a;直接复制安装好的虚拟机文…

CAP BASE理论

CAP & BASE理论详解 CAP 理论 简介 CAP 也就是 Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;、Partition Tolerance&#xff08;分区容错性&#xff09; 这三个单词首字母组合。 CAP 理论的提出者布鲁尔在提出 CAP 猜想的时…

LZW的编码和解码

不同于哈弗曼编码针对于每个元素编码&#xff0c;LZW主要针对字符串的编码优化&#xff0c;也就是把出现频率高的字符串压缩成一个字符表示&#xff0c;这也是大名鼎鼎的GIF采用的压缩格式。下面我将从三个角度谈谈我的一些理解&#xff0c;文章主要参考了这位大佬&#xff1a;…

灯光开不了了,是不是NVIDIA的问题

如果你跟我一样灯光亮度调节不了了&#xff0c;然后显示适配器又没有了&#xff0c;你看一下是不是和我这个大怨种一样把NVIDIA卸了&#xff0c;为了这个东西&#xff0c;这屏幕亮瞎我的眼镜&#x1f622;&#x1f622;。只需要进入官网&#xff0c;你就可以直接找到&#xff0…

浅析SD-WAN企业组网部署中简化网络运维的关键技术

网络已经成为现代企业不可或缺的基础设施&#xff0c;它为企业提供了连接全球的桥梁。随着全球化和数字化转型的加速推进&#xff0c;企业面临着越来越多的网络挑战和压力。传统的网络组网方式往往无法满足企业规模扩大、分支机构增多、上云服务等需求&#xff0c;导致网络性能…

005、简单页面-容器组件

之——布局 目录 之——布局 杂谈 正文 1.布局基础知识 2.Column 3.Row 4.实践 杂谈 布局容器组件。 一个丰富的页面需要很多组件组成&#xff0c;那么&#xff0c;我们如何才能让这些组件有条不紊地在页面上布局呢&#xff1f;这就需要借助容器组件来实现。 容器组件是…

深入理解Servlet(中)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 上篇有一张图&#xff…

Istio可观测性

Istio可观测性 image-20231129072302901 前言 Istio 为网格内所有的服务通信生成详细的遥测数据。这种遥测技术提供了服务行为的可观测性&#xff0c;使运维人员能够排查故障、维护和优化应用程序&#xff0c;而不会给开发人员带来其他额外的负担。通过 Istio&#xff0c;运维…

(C语言)找出1-99之间的全部同构数

同构数&#xff1a;它出现在平方数的右边。例&#xff1a;5是25右边的数&#xff0c;25是625右边的数&#xff0c;即5和25均是同构数。 #include<stdio.h> int main() {for(int i 1;i < 100;i ){if((i*i % 10 i) || (i*i % 100 i))printf("%d\t%d\n",i,…

随堂复习(异常处理、多线程)

第09章&#xff1a;随堂复习&#xff08;异常处理&#xff09; 一、随堂复习 1. 异常的概述 1. 什么是异常&#xff1f; 指的是程序在执行过程中&#xff0c;出现的非正常情况&#xff0c;如果不处理最终会导致JVM的非正常停止。2. 异常的抛出机制 Java中把不同的异常用不同的…

【文献阅读】Joint Demosaicing and Denoising with Self Guidance

1. 摘要 近年来&#xff0c;一些神经网络在联合去马赛克和去噪(JDD)方面表现出了良好的效果。大多数算法首先将Bayer原始图像分解为四通道RGGB图像&#xff0c;然后将其输入神经网络。这种做法忽略了一个事实&#xff0c;即绿色通道的采样率是红色和蓝色通道的两倍。在本文中&…

【Unity入门】声音组件AudioSource简介及实现声音的近大远小

AudioSource组件 将需要播放声音的物体挂载Audio Listener组件&#xff0c;实现声音的播放 AudioSource组件属性 &#xff08;1&#xff09;AudioClip&#xff08;音频剪辑&#xff09;&#xff1a;指定播放的音频文件。 &#xff08;2&#xff09;Output&#xff08;音频输…