最小生成树入门(图解)

article/2025/9/16 13:26:10

1.什么是最小生成树

来看百度百科的定义

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n个结点,并且有保持图连通的最少的边。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。

意思简单明了就是求最小的连通图
举个栗子

这幅图的极小连通图为

或者

就是从一个点能到达图的任意一点,且花费的代价最小(所有边的权值最小)

2.普里姆(Prim)算法

此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。

从点v1开始选择离v1最近的点,可以发现v1-v3的距离最小,所以把这条边连上

现在v1和v3作为一个整体,看那个点离v1和v3最近,此时有两个点离得最近,按顺序选择v4(也可以选择v6,是一样的)。

现在选择离v1,v3,v4最近的点,现在v4-v6这条边最短,所以选择v4-v6这条边

按照这个思路依次选择,直到把所有的点都选上

3.Prim代码

prim的核心代码为:


int prime()
{int tip = 0; //tip用来计算距离for(int i = 1 ; i <= n ; i++) // 初始化dis为无穷大dis[i] = inf;//inf = 99999999;memset(book , 0 , sizeof(book));//book用来标记点有没有被选择dis[1] = 0; //以1为结点开始for(int i = 1 ; i <= n ; i++){int k = -1 , temp = inf;for(int j = 1 ; j <= n ; j++){if(book[j] == 0 && dis[j] < temp) //在没有遍历过的顶点中找距离树最近的点{k = j;temp = dis[j];}}if(k == -1) return -1; // 有没有联通的点输出-1tip += dis[k];//记录距离book[k] = 1;  //把已经收入树的顶点标记for(int j = 1 ; j <= n ; j++) //遍历该顶点与未遍历顶点的距离 更新dis{if(book[j] == 0 && f[k][j] != inf && f[k][j] < dis[j])dis[j] = f[k][j];}}return tip;
}

4.克鲁斯卡(Kruskal)算法

并查集+贪心

算法思路:
(1)将图中的所有边都去掉。
(2)将边按权值从小到大的顺序添加到图中,保证添加的过程中不会形成环
(3)重复上一步直到连接所有顶点,此时就生成了最小生成树。
对所有的边进行排序
在这里插入图片描述

加入步骤如图
在这里插入图片描述

5.Kruskal算法代码:

#include<iostream>
#include<string>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int n , m;
int f[1005];
void init() //初始化
{for(int i = 1 ; i <= n ; i++)f[i] = i;
}
struct book //用来存储边
{int k1 , k2;//顶点int dis;//权值
}e[3005];
int getf(int v) //并查集  找“领导”的函数
{if(f[v] == v)return v;else{f[v] = getf(f[v]);return f[v];}
}
bool merge1(int x , int y) //合并顶点的函数
{int t1 , t2;t1 = getf(f[x]);t2 = getf(f[y]);if(t1 != t2) //判断顶点是否在一颗树里{ f[t2] = t1;return true;}elsereturn false;
}
bool cmp(book x , book y) //结构体排序
{return x.dis < y.dis;
}
int main()
{cin>>n>>m;init();for(int i = 1 ; i <= m ; i++)cin>>e[i].k1>>e[i].k2>>e[i].dis;sort(e+1 , e+m+1 , cmp);int ans = 0; //记录最终的权值int tip = n; //用了几条边for(int i = 1 ; i <= m ; i++){if(merge1(e[i].k1 , e[i].k2)){ans += e[i].dis;tip--;if(tip == 1)break;}}if(tip == 1)cout<<ans;elsecout<<"-1";
}

引用的具体题目为
题目链接: 公路村村通


http://chatgpt.dhexx.cn/article/8nLZMq6P.shtml

相关文章

最小生成树(Prim、Kruskal)算法,秒懂!

前言 在数据结构与算法的图论中&#xff0c;(生成)最小生成树算法是一种常用并且和生活贴切比较近的一种算法。但是可能很多人对概念不是很清楚&#xff0c;什么是最小生成树? 一个有 n 个结点的连通图的生成树是原图的极小连通子图&#xff0c;且包含原图中的所有 n 个结点&…

最小生成树详解(模板 + 例题)

作为一个伪ACMer,先来首广为人知的打油诗: 模拟只会猜题意&#xff0c;贪心只能过样例&#xff0c;数学上来先打表&#xff0c;规律一般是DP&#xff0c;组合数学碰运气&#xff0c;计算几何瞎暴力&#xff0c;图论一顿套模板&#xff0c;数论只会GCD,递归递推伤不起&#xff0…

Linux开启/关闭防火墙

一、查看防火墙状态&#xff1a; systemctl status firewalldinactive表示防火墙为关闭状态。 二、开启防火墙&#xff1a; systemctl start firewalld启动后无任何提示&#xff0c;再次查看防火墙状态&#xff0c;可以看到变成active&#xff0c;成功启动。 三、关闭防火墙…

linux服务器查看防火墙是否关闭,linux查看防火墙是否关闭了的方法

linux查看防火墙是否关闭了的方法 发布时间&#xff1a;2020-04-02 10:49:28 来源&#xff1a;亿速云 阅读&#xff1a;62 作者&#xff1a;小新 今天小编给大家分享的是linux查看防火墙是否关闭了的方法&#xff0c;很多人都不太了解&#xff0c;今天小编为了让大家更加了解li…

linux操作系统关闭防火墙,linux操作系统关闭防火墙的方法

防火墙是一项协助确保信息安全的设备,会依照特定的规则,允许或是限制传输的数据通过。简单的来说防火墙的作用就是保护你的网络免受非法用户的侵入,虽然防火墙是为了你网络安全而存在,但是同时也限制了你上网操作,有很多人会选择关闭防火墙,windows操作系统的防火墙好关闭…

linux为什么要关闭防火墙,Linux怎么样关闭防火墙

Linux系统下面自带了防火墙iptables&#xff0c;iptables可以设置很多安全规则。但是如果配置错误很容易导致各种网络问题&#xff0c;那么如果要关闭禁用防火墙怎么操作呢?下面就让学习啦小编给大家说说Linux怎么关闭防火墙吧。 Linux关闭防火墙的方法 如果启动的iptables防火…

linux防火墙的开启、关闭、永久关闭

防火墙是什么&#xff1f;我们为什么需要关闭防火墙&#xff1f; 防火墙就是一个保护我们系统的软件服务&#xff0c;默认开启&#xff0c;但是我们在实际开发中&#xff0c;如果需要使用宿主机来连接虚拟机里面的redis, mysql&#xff0c;nginx&#xff0c;tomcat等服务&#…

linux防火墙能关吗,linux防火墙怎么样关闭

有没有什么方法可以关闭linux防火墙呢?方法是有的&#xff0c;小编来告诉你!下面由学习啦小编给你做出详细的linux防火墙关闭方法介绍!希望对你有帮助! linux防火墙关闭方法一&#xff1a; 1) 重启后生效 开启&#xff1a; chkconfig iptables on 关闭&#xff1a; chkconfig …

Linux防火墙关闭(重启)操作(centos)

1:查看防火墙状态 systemctl statu firewalld 此状态表示防火墙禁用状态 此状态表示防火墙处于开启状态 2:暂时关闭防火墙 systemctl stop firewalld 3:启用防火墙&#xff08;关闭状态使用&#xff09; systemctl start firewalld 4:重启防火墙&#xff08;输入命令后防火墙先…

Linux 开启关闭防火墙操作

1. linux中防火墙相关操作 1.1 查看防火墙状态 systemctl status firewalld如下所示表示防火墙是运行状态&#xff0c; 8080&#xff0c; 3306&#xff0c; 6379表示我开放了这个端口给外部访问 或者 firewall-cmd --state1.2 暂时关闭防火墙(重启服务器防火墙会重新开启) …

【Linux】如何关闭Linux防火墙

在访问linux时&#xff0c;如果linux防火墙是开启状态&#xff0c;则无法访问其提供的服务&#xff0c;为此&#xff0c;需要将Linux的防火墙关闭&#xff0c;命令如下[1]&#xff1a; 查看防火墙状态 firewall -cmd --state关闭防火墙 systemctl stop firewalld.serv…

linux防火墙关闭启用增减端口号命令

查看防火墙信息 firewall-cmd --list-all 查看防火墙状态 firewall-cmd --state systemctl status firewalld 添加端口号到防火墙中&#xff0c;永久有效是写入配置文件&#xff0c;可以不加--permanent但重启服务器后会失效 firewall-cmd --permanent --add-port18082/tcp …

Linux防火墙的关闭

查看防火墙的状态 打开终端输入如下命令 systemctl status firewalld 如图所示&#xff1a;running表示防火墙目前处于打开状态 输入命令进行关闭防火墙&#xff1a; systemctl stop firewalld 如图所示正常的用户是没有权限的&#xff0c;需要输入管理员的密码才能够进行关闭防…

python随机抽取样本1500个_(python)随机抽样

随机抽样法就是调查对象总体中每个部分都有同等被抽中的可能,是一种完全依照机会均等的原则进行的抽样调查,被称为是一种“等概率”.随机抽样有四种基本形式,即简单随机抽样、等距抽样、类型抽样和整群抽样. 非随机抽样的定义&#xff1a;指抽样时不是遵循随机原则,而是按照研究…

抽样技术--简单随机抽样

文章目录 简单随机抽样简单估计量及其性质对总体均值的估计简单随机抽样简单例子 对总体总量的估计例子 对总体比例的估计例子 比率估计量及其性质辅助变量比率估计量总体均值的期望咋算总体均值的方差咋算总体总值的期望咋算总体总值的方差咋算比率估计量的方差咋算Y与X的总体…

R - 简单随机抽样

本文使用的包 library(tidyverse) library(moderndive)使用的数据集&#xff0c;总共有2400个红球和白色球&#xff1a; bowl此处采用简单随机抽样&#xff0c;从2400个球中估算出红球所占比例。采用不同的抽取方法&#xff0c;一组是一次性抽取30个&#xff0c;重复1000次&a…

随机抽样java_java实现从一个群体中随机抽样一定数量样本

说明 版权所有&#xff0c;仿冒必究 转载时请标明出处&#xff0c;尊重他人劳动成果&#xff0c;谢谢 此算法是我个人研究的&#xff0c;经过测试证明我的算法还是不错的。 PS&#xff1a;这里的时间可能有点偏小&#xff0c;实际用时是2秒左右&#xff0c;我没有去研究原因了。…

ArcGIS 分类随机抽样

前言 现有栅格分类图, 图中像素值代表分类编号, 取值范围为0~7。 要在每个类别中抽取100个点, 输出成带有类别的shape文件。 提取每类的随机点(流程图) 0 已有数据 一副栅格影像, 像素值代表该点的类别。 1 对类别进行循环 设置1~7的循环, 循环变量名为index。在之后的流…

java随机抽样算法_随机抽样一致性(RANSAC)算法详解

随机抽样一致性(RANSAC)算法能够有效的剔除特征匹配中的错误匹配点。 实际上&#xff0c;RANSAC能够有效拟合存在噪声模型下的拟合函数。实际上&#xff0c;RANSAC算法的核心在于将点划分为“内点”和“外点”。在一组包含“外点”的数据集中&#xff0c;采用不断迭代的方法&am…

SPSS——随机抽样

简单随机抽样 设定随机种子&#xff08;Transform→Random Number Generators&#xff09; 【方法一】 选择个案&#xff08;Data→Select Cases&#xff09; 将随机抽样的样本重新生成新的数据集&#xff0c;Approximately&#xff08;按百分比抽样&#xff09;&#xff0c;Ex…