上篇Prim算法简要的讲解了最小生成树。也提到过Prim算法堆优化,但本蒟蒻并没有贴Prim         (堆优化的代码)。至于为什么没有贴呢?上篇Prim算法blog末尾有说明。

好勒!咱们接着讲Kruskal算法。这跟Prim算法有很大的不同

Prim和Kruskal算法差异:

1:Prim复杂度为O(n^2+m)   而Kruskal的复杂度为O(mlogm)    //注:n:点数    m:边数

2:Prim算法思想是枚举点的联通情况进行延伸计算,因此枚举每个点造成了n^2的复杂度,而Kruskal的算法思想是枚举边的情况,之大大减少了枚举的数量且减少了复杂度

Kruskal基本思想:

克鲁斯卡尔(Kruskal)算法从另一途径求网的最小生成树。其基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),概述图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止。

Kruskal方法构造最小生成树的过程图解:

按权值由小到大的顺序排列的编辑是:(各边由起点序号,终点序号,权值表示)

1.(4,6,30)   2.(2,5,40)   3.(4,7,42)   4.(3,7,45)   5.(1,2,50)   6.(4,5,50)   7.(3,4,52)   8.(1,3,60)

9.(2,4,65)  10.(5, 6, 70)

克鲁斯卡尔算法思想设计克鲁斯卡尔算法函数主要包括两个部分:首先是带权图G中e条边的权值的排序;其次是判断新选取的边的两个顶点是否属于同一个连通分量。对带权图G中e条边的权值的排序方法可以有很多种,各自的时间复杂度均不相同,对e条边的权值排序算法时间复杂度较好的算法有快速排序法、堆排序法等,这些排序算法的时间复杂度均可以达到O(elge)。判断新选取的边的两个顶点是否属于同一个连通分量的问题是一个在最多有n个顶点的生成树中遍历寻找新选取的边的两个顶点是否存在的问题,此算法的时间复杂度最坏情况下为O(n)

观察Kruskal算法:

无向连通网的最小生成树首先是一棵生成树,即它应该是一个使网中所有顶点相连通而所需边的条数为最小的子网络,且其代价和在所有生成树中为最小。因此,可以从网的连通性角度来观察Kruskal算法。

初始时,最小生成树就是网中所有顶点的集合,它们之间没有任何一条边连接,即它们自成一个连通分量。而Kruskal算法的执行过程其实就是一个选取网中权值为最小的边的过程,即将两个小的连通分量连接为较大的连通分量,直至所有顶点都在一个连通分量中为止。每当选取网中的一条边时总会出现以下两种情况之一:

①该边所依附的两个顶点分属于不同的连通分量。这时,该边可以作为最小生成树的一条边,因为两个不同的连通分量通过这条边的连接而相连通,成为了一个连通分量 。

②该边所依附的两个顶点属于同一个连通分量。如果选取这条边作为最小生成树的一条边,则必将构成环。因为连通分量中任意两个顶点间都有路径相通,一旦再加入一条边,该边所依附的两个顶点之间就有了两条路径,即构成了环。故属于这种情况的边即使其权值小也应该舍弃

再结合例题+代码的方式进行讲解:

小二,上题!

例题:链接:http://oj.daimayuan.top/course/14/problem/691

代码实现:

//Kruskal算法:O(mlogm): m为边的数量
#include<bits/stdc++.h>//万能头文件
using namespace std;
const int M=100002;//边的数量
const int N=50001;//点的数量
struct Node//定义一个包含起点,终点,边权的结构体
{int x,y,v;bool operator<(const Node &A) const//重构//目的是进行边权由小到排序{return v<A.v;}
}a[M];int n,m,fa[N];
//并查集的基本操作,在数据结构专题里我有讲解,大佬们要是忘记了,可以去看看
int Find(int x)//找父节点
{if(x==fa[x]) return x;return fa[x]=Find(fa[x]);
}
//Kruskal算法
int Kruskal()
{for(int i=1;i<=n;i++) fa[i]=i;//初始化父节点sort(a+1,a+1+m);//将边权排序int ans=0,cnt=n;//ans记录最小生成树的值,cnt代表有多少个集合for(int i=1;i<=m;i++)//枚举边{int x=Find(a[i].x),y=Find(a[i].y);//找起点和终点所属的集合if(x!=y)//若是不在一个集合(父节点){fa[x]=y;//进行合并操作ans+=a[i].v;//加最小边权--cnt;//总集合树-1}if(cnt==1) break;//如果最终只有一个集合,说明已经生成了最小生成树,就结束循环}if(cnt!=1) return -1;//如果不为一个集合,返回-1else return ans;//否则返回最小生成树值
}int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)//存图操作scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);printf("%d",Kruskal());
}

总结:

1.最小生成树的算法分为两种: Prim算法和Kruskal(本蒟蒻目前就只知道这两种)

2.Prim是在点上的操作,Kruskal是在边上的操作

3.Prim算法复杂度:O(n^2+m)               Prim(堆优化):O((m+n)logn) 

   Kruskal算法复杂度:O(mlogm)

来都来了,给个点赞和关注呗(路过的给本蒟蒻一个赞也行...QAQ)

Kruskal算法(最小生成树)相关推荐

  1. Kruskal算法 最小生成树

    Kruskal算法 Kruskal的由来 Prim算法利用了MST的性质:假设N= (V,E)是一个连通图,U是顶点集V的一个非空子集,若(u,v)是一条最小权值的边,其中u属于U,v属于V-U,则必 ...

  2. 求的带权图最小生成树的Prim算法和Kruskal算法

    求的带权图最小生成树的Prim算法和Kruskal算法 最小生成树的概念 最小生成树其实是最小权重生成树的简称. 一个连通图可能有多个生成树.当图中的边具有权值时,总会有一个生成树的边的权值之和小于或 ...

  3. Kruskal求最小生成树

    Kruskal算法最小生成树 #include <iostream> #include <cstdio> #include <cstring> #include & ...

  4. 数据结构与算法(7-3)最小生成树(普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法)

    目录 一.最小生成树简介 二.普里姆算法(Prim) 1.原理 2.存储 2-1.图顶点和权: 2-3. 最小生成树: 3.Prim()函数 3-1.新顶点入树 3-2.保留最小权 3-3. 找到最小 ...

  5. 【数据结构】最小生成树 Prim算法 Kruskal算法

    最小生成树应用场景: 假设以下场景,有一块木板,板上钉上一些钉子,这些钉子可以由一些细绳连接起来.假设每个钉子可以通过一根或者多根细绳连接起来,那么一定存在这样得情况,即用最少的细绳把所有的钉子连接起 ...

  6. ds图—最小生成树_Java: Kruskal算法生成最小生成树(邻接矩阵)

    Java: Kruskal算法生成最小生成树(邻接矩阵): package 输出: Kruskal=36: (E,F) (C,D) (D,E) (B,F) (E,G) (A,B) 分析: Java: ...

  7. 生成树的概念,最小生成树Prim算法 Kruskal算法

    求解最小生成树可以用Prim算法 Kruskal算法

  8. Kruskal算法构造最小生成树

    问题[描述算法问题,首选形式化方式(数学语言),其次才是非形式化方式(日常语言)] 在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) ...

  9. Prim算法和Kruskal算法求最小生成树

    Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...

  10. 生成随机数放入整型数组怎么判断有没有重复_图的应用(1)-连通图的最小生成树(Prim算法和Kruskal算法)...

    连通图的生成树: 是一个极小的连通图,它含有图中全部的N个顶点,但是只足以构成一颗树的N-1条边. 必须满足三个条件: 图是连通图: 图中包含了N个结点 图中边的数量等于N-1条. 连通图生成树的判断 ...

最新文章

  1. redis的scan命令的源码分析,实现原理
  2. overleaf创建表格
  3. 不同型号的二极管模块并联_电阻可以串联,为何二极管不适合串联?
  4. python 与或非_Python的阶乘求和
  5. vue-cli3项目中全局引入less sass文件 以及使用本地图片在不同地方规则
  6. Hibdernate入门
  7. python字符串格式化符号含义及转义字符含义
  8. 学术资源不定期分享-【钱学森《工程控制论》英文原版】
  9. Linux基础知识 | vi编辑器
  10. 基于Flutter的m3u8下载器
  11. 常用 ajax js 表单
  12. [语音处理] 声谱图(spectrogram)FBank(Mel_spectrogram)MFCC(Mel倒谱)到底用哪个作为NN输入?
  13. 第1节 细胞是生命活动的基本单位
  14. RabbitMQ基础知识
  15. 如何做到3个月吸粉10多万
  16. 学习笔记 —— 基于C加速的Python高效计算 (Cython pybind11)
  17. 自由人NFT:数字藏品乱象中,我们如何辨别?
  18. 纽约州立大学水牛城分校计算机科学专业,美国布法罗大学(纽约州立大学水牛城分校)介绍/专业/申请条件/奖学金 | Hotcourses中国...
  19. m4s转为mp4实例:使用ffmpeg和批处理将m4s转为mp4
  20. 关于薪水保险金的那些事

热门文章

  1. MUSBMHDRC USB 2.0 MULTI-POINT DUAL-ROLE CONTROLLER编程指南解读2
  2. Linux系统之软件管理
  3. 【分享NVIDIA GTC大会干货】与Jetson嵌入式平台工程师的深度挖掘问答
  4. transactionTemplate???
  5. iphone11系列的尺寸_iPhone12太贵,苹果双11销量还得看iPhone11,3XXX起有戏!
  6. 如何用WebGPU流畅渲染千万级2D物体:基于光追管线
  7. 陕西师范大学计算机学院课表,2019年陕西师范大学数学与信息科学学院课程表.doc...
  8. adrc过渡过程 c语言,初步认识ADRC与应用
  9. 计算机病毒的六大特征:
  10. 一夜爆火!这款换脸 App 可能会把你的脸 卖掉