Kruskal算法

步骤:

第一步:给所有边按照从小到大顺序排列(直接使用库函数qsort / sort)。

第二步:从小到大依次考察每条边(u,v),在执行第二步时会出现以下两种情况:

情况1:u和v在同一连通分量中,加入(u,v)会形成环,因此不能选择。

情况2:u和v在不同的连通分量中,加入(u,v)就一定是最优的。

伪代码:

(1)   把所有的程序排序,记第i小的边为e[i]  (1<=i<m)

(2)   初始化MST为空

(3)   初始化连通分量,让每个点自成一个独立的连通分量

for ( int i = 0; i<m; i++)

if(e[i].u和e[i].v不在一个连通分量)

{

把e[i] 加入MST中

合并e[i].u和e[i].v所在的连通分量

}

分析:

该算法关键点在于“连通分量的查询与合并”——需要知道任意两个点是否在同一个连通分量中,还需要合并两个连通分量。

解决方法:

(1)     暴力求解法:

(2)     使用并查集(Union-Find Set)

代码:(使用并查集方法)

//Kruskal算法
//假设第i条边的两个端点序号和权值分别保存在u[i],v[i]和w[i]中
//排序后第i小的边的序号保存在r[i]中
int cmp(const int i,const int j)             //间接排序函数
{return w[i]<w[j];
}
int find(int x)                              //并查集的find
{return p[x] == x ? x : p[x] = find(p[x]);//如果 p[x] = x,说明x本身是树根,因此返回x;否则返回p[x]的父节点所在树的树根
}
int Kruskal()
{int ans = 0;for(int i = 0;i < n;i++)//初始化并查集p[i]=i;for(int i = 0;i < m;i++)//初始化边序号r[i]=i;sort(r ,r+m ,cmp);//给边排序for(int i = 0; i<m; i++){int e = r[i]; int x = find(u[e]); //找出当前边两个端点所在的集合编号int y = find(v[e]);if(x !=y)//如果在不同集合合并{ans += w[e];p[x] = y;}}}

并查集:(Union-Find Set)

原理:

使用树来表示集合,树的每个节点就表示集合中的一个元素,树根对应的元素就是该集合的代表元(representative).

特点:

每个连通分量看作是一个集合,该集合包含了连通分量的所有点。这些点两两相通,具体的连接方式无关紧要。

基本操作

  1. makeSet(s):建立一个新的并查集,其中包含 s 个单元素集合。
  2. unionSet(x, y):把元素 x 和元素 y 所在的集合合并,要求 x 和 y 所在的集合不相交,如果相交则不合并。
  3. find(x):找到元素 x 所在的集合的代表元(即父节点),该操作也可以用于判断两个元素是否位于同一个集合,只要将它们各自的代表比较一下就可以了。

find(x)函数:查找结点x所在树的根节点的递归程序(把x的父节点保存在p[x]中)

int find(int x)
{ p[x] == x ? x : p[x] = find(p[x]);}

如果 p[x] = x,说明x本身是树根,因此返回x;否则返回p[x]的父节点所在树的树根。

特殊情况下:一棵树是一个长长的链,链的最后一个节点为x。

在执行find函数时:每次执行find(x)都会遍历整条链,效率低下。

根据并查集的特点:连通分量中点两两相通,具体的连接方式无关紧要。即树的形态无关紧要。可以做出优化---并查集中的路径压缩

路径压缩:

并查集在每次查找时,令查找路径上的每个节点都直接指向根节点。

Kruskal算法和并查集相关推荐

  1. Kruskal算法与并查集

    Kruskal算法与并查集 一.Kruskal算法 1. 概念 Kruskal算法就是按照图中各个边上的权值大小进行递增排序,以此来构造最小生成树. 2.重点解析 在由Kruskal实现最小生成树的过 ...

  2. 【算法】并查集的运用

    并查集的概念 朋友圈 团伙问题 连通图 总结 并查集的概念 并查集顾名思义就是合并和查找,问题在于合并什么,查找什么.这里有一种朴素的思想来解释这两个问题.就是把这个想成一棵树.合并什么?就是把不在这 ...

  3. 简单易懂的并查集算法以及并查集实战演练

    文章目录 前言 一.引例 二.结合引例写出并查集 1. 并查集维护一个数组 2. 并查集的 并 操作 3. 并查集的 查 操作 4. 基本并查集模板代码实现--第一版(有错误后面分析) 4.1 Jav ...

  4. 算法总结 — 并查集

    参考:算法学习笔记(1) : 并查集 - 知乎 并查集 (disjoint set union) 是 最优美的数据结构之一 合并 (merge): 把两个集合合并 查找 (find): 查找一个元素的 ...

  5. 算法:并查集(四种方式)

    简单并查集 public class UnionFind {private int[] id;private int count;public UnionFind(int N) {count = N; ...

  6. Java实现_算法_并查集

    并查集 作用:用来查找某个图中是否含有闭环. 比如图一: 上图中就是没有闭环的一个图,而下图(图二)就是一个有闭环的图 思路1-数组寻根法: 顾名思义,数组寻根法(自己称呼的)就是寻找每个节点的根节点 ...

  7. 【算法】并查集刷题总结

    目录 P1396 营救 题目描述 "咚咚咚--""查水表!"原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门-- 妈妈下班回家, ...

  8. python【数据结构与算法】并查集引入

    文章目录 1 并查集 2 策略 3 代码 1 并查集 Disjoint Set,实际上字面翻译是不相交的集合. 中文名 "并查集" 实际上源自其基本操作: union(X,Y):求 ...

  9. 算法(并查集--合并集合)

    并查集–合并集合 一共有n个数,编号是1~n,最开始每个数各自在一个集合中. 现在要进行m个操作,操作共有两种: "M a b",将编号为a和b的两个数所在的集合合并,如果两个数已 ...

最新文章

  1. 制作一个简易的QQ×××
  2. php-5.2.3.tar.bz2.gz 的解压方法
  3. REVERSE-PRACTICE-BUUCTF-8
  4. 启动django服务器报错raise errorclass(errno, errval) django.db.utils.InternalError
  5. 关于C++中的pow()函数
  6. mysql 双主 脑裂_MySQL双主(主主)架构方案
  7. oracle+查表物理块数,查询Oracle表实际物理使用大小
  8. 扇贝和不背单词_你还没找到中意的背单词APP?我都试过,我来帮你盘点盘点
  9. SVN客户端安装及使用
  10. autojs识别数字ocr
  11. 谷歌引擎html,国内免费使用谷歌翻译引擎
  12. FFmpeg进行推流的两种方法
  13. linux安装安卓fastboot,Android的fastboot协议
  14. 好用用的linux 监控命令
  15. matlab 定义结构体数组,结构体数组及其定义和使用,C语言结构体数组详解
  16. 1-3 Python基本数据类型
  17. Flutter第3天--基础控件(上)
  18. 环艺考计算机英语吗,应届考取北理环艺分享|愿汗水泪水都不会被辜负!
  19. ubuntu安装ActiveMQ
  20. 解决-最新版Google谷歌浏览器谷歌浏览器Chrome一上传或者下载附件图片就未响应卡死

热门文章

  1. 如何更改 think-cell 图表的默认颜色?使用教程
  2. traffic server文件目录
  3. 用顺序表实现学生信息管理系统
  4. 周鸿一传:中国互联网流氓教父的前世今生
  5. Lattice Diamond与modelsim联合仿真环境设置
  6. 网络调试助手 TCPsever无法连接
  7. echarts折线图,散点和折线点的点击事件
  8. 诚邀您体验人工智能AI
  9. HTML 创建按钮实现跳转链接
  10. SysDVR Switch 串流到笔记本