kruskal算法【最小生成树2】
设G=(V,E)是无向连通带权图,V={1,2,…,n};
设最小生成树T=(V,TE),该树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),Kruskal算法将这n个顶点看成是n个孤立的连通分支。
它首先将所有的边按权值从小到大排序,然后只要T中选中的边数不到n-1,就做如下的贪心选择:
在边集E中选取权值最小的边(i,j),如果将边(i,j)加入集合TE中不产生回路(圈),则将边(i,j)加入边集TE中,即用边(i,j)将这两个连通分支合并连接成一个连通分支;
否则继续选择下一条最短边。把边(i,j)从集合E中删去。
继续上面的贪心选择,直到T中所有顶点都在同一个连通分支上为止。
此时,选取到的n-1条边恰好构成G的一棵最小生成树T。
那么,怎样判断加入某条边后图T会不会出现回路呢?
该算法对于手工计算十分方便,因为用肉眼可以很容易看到挑选哪些边能够避免构成回路(避圈法),但使用计算机程序来实现时,还需要一种机制来进行判断。
Kruskal算法用了一个非常聪明的方法,就是运用集合避圈:
如果所选择加入的边的起点和终点都在T的集合中,那么就可以断定一定会形成回路(圈)。其实就是我们前面提到的“避圈法”:边的两个结点不能属于同一集合。
步骤1:初始化。将图G的边集E中的所有边按权值从小到大排序,边集TE={},把每个顶点都初始化为一个孤立的分支,即一个顶点对应一个集合。
步骤2:在E中寻找权值最小的边(i,j)。
步骤3:如果顶点i和位于两个不同连通分支,则将边(i,j)加入边集TE,并执行合并操作,将两个连通分支进行合并【即两个顶点设置成同一个集合号,一般向小集合号合并】。
步骤4:将边(i,j)从集合E中删去,即E=E-{(i,j)}。
步骤5:如果选取边数小于n-1,转步骤2;否则,算法结束,生成最小生成树了。
适用范围:要求无向图
kruskal算法(读者可以将其读作“克鲁斯卡尔算法”同样是解决最小生成树问题的一个算法。和prim算法不同,kruskal算法采用了边贪心的策略,其思想极其简洁,理解难度比prim算法要低很多。
kruskal算法的基本思想为:在初始状态时隐去图中的所有边,这样图中每个顶点都自成一个连通块。
之后执行下面的步骤:
①对所有边按边权从小到大进行排序。
②按边权从小到大测试所有边,如果当前测试边所连接的两个顶点不在同一个连通块中,则把这条测试边加入当前最小生成树中;否则,将边舍弃。
③执行步骤②,直到最小生成树中的边数等于总顶点数减1或是测试完所有边时结束。
而当结束时如果最小生成树的边数小于总顶点数减1,说明该图不连通。
接下来以图10-51a为例,给出对该图执行kruskal算法的步骤。
①当前图中边权最小的边为V。V,权值为1。由于Vo和V4在不同的连通块中,因此把边VoVa加入最小生成树中,此时最小生成树中有1条边,权值之和为1,如图10-51所示。
因此,kruskal算法的思想简单说来就是:
每次选择图中最小边权的边,如果边两端的顶点在不同的连通块中,就把这条边加入最小生成树中。
//边集定义部分
struct edge
{
int u,v;//边的两个端点编号
int cost;//边权
}E[MAXE];//最多有MAXE条边 bool cmp(edge a,edge b)
{
return a.cost <b.cost;
} //并查集部分
int father[MAXV];//并查集数组
int findFather(int x)
{//并查集查询函数
int a=x;
while(x!=father[x])
x=father[x];
//路径压缩
while(a!=father[a])
{
int z = a;
a = father[a];
father[z]=x;
}
return x;
} //kruskal部分,返回最小生成树的边权之和,参数n为顶点个数,m为图的边数
int kruskal(int n,int m)
{//ans为所求边权之和,Num Edge为当前生成树的边数
int ans=,Num Edge=;
for(int i=;i<n;i++)//顶点范围是[0,n-1]
father[i]=i;//并查集初始化
sort(E,E+m,cmp);//所有边按边权从小到大排序
for(int i=;i<m;i++)
{//枚举所有边
int faU=findFather(E[i].u);//查询测试边两个端点所在集合的根结点
int faV=findFather(E[i].v);
if(faU!=faV)
{//如果不在一个集合中
father[faU]=faV;//合并集合(即把测试边加入最小生成树中)
ans += E[i].cost;//边权之和增加测试边的边权
Num_Edge++;//当前生成树的边数加1
if(Num_Edge == n-)
break;//边数等于顶点数减1时结束算法
}
}
if(Num_Edge!=n-)
return -;//无法连通时返回-1
else
return ans;//返回最小生成树的边权之和
}
kruskal算法【最小生成树2】的更多相关文章
- Kruskal算法-最小生成树
2017-07-26 10:32:07 writer:pprp Kruskal算法是根据边的加权值以递增的方式,一次找出加权值最低的边来建最小生成树:并且每次添加的边不能造成生成树有回路,直到找到N ...
- POJ-2349(kruskal算法+最小生成树中最大边的长度)
Arctic POJ-2349 这题是最小生成树的变形题目.题目的意思是已经有s个卫星频道,这几个卫星频道可以构成一部分的网络,而且不用费用,剩下的需要靠d的卫星接收器.题目要求的就是最小生成树中,最 ...
- 最小生成树---Prim算法和Kruskal算法
Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...
- 最小生成树的Kruskal算法实现
最近在复习数据结构,所以想起了之前做的一个最小生成树算法.用Kruskal算法实现的,结合堆排序可以复习回顾数据结构.现在写出来与大家分享. 最小生成树算法思想:书上说的是在一给定的无向图G = (V ...
- 最小生成树——kruskal算法
kruskal和prim都是解决最小生成树问题,都是选取最小边,但kruskal是通过对所有边按从小到大的顺序排过一次序之后,配合并查集实现的.我们取出一条边,判断如果它的始点和终点属于同一棵树,那么 ...
- 贪心算法-最小生成树Kruskal算法和Prim算法
Kruskal算法: 不断地选择未被选中的边中权重最轻且不会形成环的一条. 简单的理解: 不停地循环,每一次都寻找两个顶点,这两个顶点不在同一个真子集里,且边上的权值最小. 把找到的这两个顶点联合起来 ...
- Prim算法和Kruskal算法(图论中的最小生成树算法)
最小生成树在一个图中可以有多个,但是如果一个图中边的权值互不相同的话,那么最小生成树只可能存在一个,用反证法很容易就证明出来了. 当然最小生成树也是一个图中包含所有节点的权值和最低的子图. 在一个图中 ...
- 邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)
matrix.c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include < ...
- 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind
最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...
- 最小生成树Kruskal算法
Kruskal算法就是把图中的所有边权值排序,然后从最小的边权值开始查找,连接图中的点,当该边的权值较小,但是连接在途中后会形成回路时就舍弃该边,寻找下一边,以此类推,假设有n个点,则只需要查找n-1 ...
随机推荐
- 爱奇艺面试Python,竟然挂在第5轮…(转)
今天给大家分享我曾经在爱奇艺的面试,过程还是比较有意思的,可以给大家一些参考 聊骚阶段 嗲妹妹:你好,我是爱奇艺的HR,我们正在招聘运维开发岗位,请问您最近有在看工作机会吗? 我:(这声音也太酥了吧我 ...
- 苹果系统下的浏览器 Date方法处理
1.做了一个活动,需要用到倒计时.比较坑的是苹果下的浏览器不识别new Date("2018-12-23 10:00:00").getTime()格式.所以孕育了一个bug小生命. ...
- 搭建邮件服务器 使用Postfix与Dovecot
首先需要从yum中下载安装三个服务:bind-chroot postfix dovecot 配置文件依次: /etc/named.conf 下载安装完后要开启的服务:named ...
- Cocos2d Box2D之浮动刚体
| 版权声明:本文为博主原创文章,未经博主允许不得转载. b2_kinematicBody 运动学物体在模拟环境中根据自身的速度进行移动.运动学物体自身不受力的作用.虽然用户可以手动移动它,但是通 ...
- FZU 2060 The Sum of Sub-matrices(状态压缩DP)
The Sum of Sub-matrices Description Seen draw a big 3*n matrix , whose entries Ai,j are all integer ...
- c# 遍历 Mysql 所有表所有列,查找目标数据
在 Mysql 的 information_schema 库中 COLUMNS 表中存放了所有表的所有列. using MySql.Data.MySqlClient; using System; us ...
- terminal Failed to fork(connot allocate memory)问题处理
今天遇到服务器无法SSH,VNC操作命令提示fork:cannot allocate memory free查看内存还有(注意,命令可能要多敲几次才会出来) 查看最大进程数 sysctl kernel ...
- 【记录】STS设置maven远程仓库,加快下载jar包
在STS中windows->preferences->maven->user settings 修改user settings里setting.xml配置文件 <?xml ve ...
- shutdown - 关闭系统
总览 SYNOPSIS /sbin/shutdown [-t sec] [-arkhncfF] time [warning-message] 描述 DESCRIPTION shutdown 以一种安全 ...
- Django版本更新(升级)到指定版本的命令