Kruskal算法来构造最小生成树,我总结了分为以下步骤:

(1)建图,构造Kruskal边集,边集元素应该包括该边的起始顶点、终止顶点、权值;

(2)将边集按权值从小到大的顺序进行排序;

(3)从小到大依次从Kruskal边集中取边加入最小生成树集合,判断条件:将该边加入最小生成树集合,与生成树集合中原有的边不构成环;

(4)最小生成树集合中元素(构成生成树的边)的个数为原图顶点数-1时,代表最小生成树构造完毕。

Kruskal核心伪代码如下:

Kruskal(MGragh *Gra)
{
对Kruskal边集按权值从小到大排序 for (边集)
{
// 判断边集中的边能否加入最小生成树集合 n=该边的起始顶点所能到达的最新顶点
m=该边的终止顶点所能到达的最新顶点 如果n等于m 说明该边能够成环路,所以不能加入最小生成树集合 如果n不等于m 说明该边可以加入最小生成树集合
{
更新:n能够到达m
}
}
}

实例:

源代码:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MAX_VERTEX_NUM 100
#define MAX_EDGE_NUM 200
#define MAX_VERTEX_NAMELEN 100 typedef struct{
char name[MAX_VERTEX_NAMELEN];
}VerType; // 图的邻接矩阵存储结构
typedef struct{
int VertexNum,EdgeNum; // 顶点数,边数
VerType Vertex[MAX_VERTEX_NUM]; // 顶点集
int Edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 边集
}MGragh; // 克鲁斯卡尔边集
typedef struct{
int b; // 起始顶点
int e; // 终结顶点
int w; // 权值
}KruskalEdge;
KruskalEdge edge[MAX_EDGE_NUM]; // 快速排序cmp
int cmp(const void *a, const void *b)
{
KruskalEdge *c = (KruskalEdge *)a;
KruskalEdge *d = (KruskalEdge *)b; // 权值从小到大排序 权值相同则按起始顶点从小到大排序
if (c->w != d->w){
return c->w - d->w;
}
else{
return c->b - d->b;
}
} // 邻接矩阵建图及建立克鲁斯卡尔边集
void CreateMGragh(MGragh *Gra)
{
int i,j,k,w;
char v1[MAX_VERTEX_NAMELEN],v2[MAX_VERTEX_NAMELEN]; printf("请输入顶点数及边数(顶点数 边数)\n");
scanf("%d %d%*c",&(Gra->VertexNum),&(Gra->EdgeNum)); printf("请输入顶点信息\n");
for (i=; i<Gra->VertexNum; i++){
printf("%d.",i+);
gets(Gra->Vertex[i].name);
} // 初始化邻接矩阵
for (i=; i<Gra->VertexNum; i++){
for (j=; j<Gra->VertexNum; j++){
Gra->Edge[i][j] = ;
}
}
printf("请输入边信息(顶点,顶点,权值)\n");
for (i=; i<Gra->EdgeNum; i++){
printf("%d.",i+);
scanf("%[^,]%*c%[^,]%*c%d%*c",v1,v2,&w); for (j=; j<Gra->VertexNum; j++){
for (k=; k<Gra->VertexNum; k++){
if (strcmp(Gra->Vertex[j].name,v1) == && strcmp(Gra->Vertex[k].name,v2) == ){
Gra->Edge[j][k] = Gra->Edge[k][j] = w; // 构造克鲁斯卡尔边集 使起始顶点<终止顶点
if (j<k){
edge[i].b = j;
edge[i].e = k;
edge[i].w = w;
}
else{
edge[i].b = k;
edge[i].e = j;
edge[i].w = w;
}
}
}
}
} // 将克鲁斯卡尔边集按权值从小到大排序
qsort(edge,Gra->EdgeNum,sizeof(edge[]),cmp);
} // 找到顶点t所能到达的在时间顺序上最新的点
// 例如p[0]=6 代表第0个点能够到达第6个点
int FindLastArrived(int *p, int t)
{
while (p[t] > ){
t = p[t];
}
return t;
} // 克鲁斯卡尔算法构造最小生成树
void MiniTreeByKruskal(MGragh *Gra)
{
int i,n,m;
int p[MAX_VERTEX_NUM]; // 初始化辅助数组
for (i=; i<Gra->VertexNum; i++){
p[i] = ;
} printf("\nKruskal算法构造最小生成树为:\n");
for (i=; i<Gra->EdgeNum; i++){
n = FindLastArrived(p,edge[i].b);
m = FindLastArrived(p,edge[i].e);
if (n != m){ // 如果n==m 说明存在环路
p[n] = m; // 将边加入生成树,并令n能到达m
printf("(%s --> %s) %d\n",Gra->Vertex[edge[i].b].name,Gra->Vertex[edge[i].e].name,edge[i].w);
}
}
} int main()
{
MGragh g;
CreateMGragh(&g);
MiniTreeByKruskal(&g);
return ;
}

测试用例及结果:

Kruskal算法构造最小生成树的更多相关文章

  1. c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树

    c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路 ...

  2. c/c++ 用普利姆(prim)算法构造最小生成树

    c/c++ 用普利姆(prim)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: ​ 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路.这时 ...

  3. 图的建立(邻接矩阵)+深度优先遍历+广度优先遍历+Prim算法构造最小生成树(Java语言描述)

    主要参考资料:数据结构(C语言版)严蔚敏   ,http://blog.chinaunix.net/uid-25324849-id-2182922.html   代码测试通过. package 图的建 ...

  4. 利用Kruskal算法求最小生成树解决聪明的猴子问题 -- 数据结构

    题目:聪明的猴子 链接:https://ac.nowcoder.com/acm/problem/19964 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个 ...

  5. kruskal算法求最小生成树(jungle roads的kruskal解法)

    注意: 注意数组越界问题(提交出现runtimeError代表数组越界) 刚开始提交的时候,边集中边的数目和点集中点的数目用的同一个宏定义,但是宏定义是按照点的最大数定义的,所以提交的时候出现了数组越 ...

  6. 克鲁斯卡尔(Kruskal)算法求最小生成树

    /* *Kruskal算法求MST */ #include <iostream> #include <cstdio> #include <cstring> #inc ...

  7. Prim算法、Kruskal算法和最小生成树 | Minimum Spanning Tree

    graph to tree非常有趣! 距离的度量会极大地影响后续的分析,欧式距离会放大差异,相关性会缩小差异,导致某些细胞群分不开. 先直观看一下,第一个是Prim,第二个是Kruskal.但是肯定都 ...

  8. Kruskal算法:最小生成树

    //Kruskal算法按照边的权值从小到大查看一遍,如果不产生圈(重边等也算在内),就把当前这条表加入到生成树中. //如果判断是否产生圈.假设现在要把连接顶点u和顶点v的边e加入生成树中.如果加入之 ...

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

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

随机推荐

  1. OpenJudge/Poj 1517 u Calculate e

    1.链接地址: http://bailian.openjudge.cn/practice/1517 http://poj.org/problem?id=1517 2.题目: 总时间限制: 1000ms ...

  2. WebConfig加密解密

    加密:aspnet_regiis -pef appSettings "G:\FlyMusicNew\Web"解密:aspnet_regiis -pdf appSettings &q ...

  3. ECMAScript位操作符

    在ECMAScript中,有少数的几个操作符可以对二进制位进行直接操作,这几个操作符本身直接对二进制进行操作,所有它们的本身是非常效率的,学习这一段有助于以后的优化以及理解. ECMAScript中采 ...

  4. web开发工具IDE

    1.NetBeans 2.Zend Studio 3.JetBrains WebStorm 4.JetBrains PhpStorm 5.Koala 6.Ionic Lab 7.sublime 8.N ...

  5. 解决treeview的同一节点单击多次的执行问题

    在使用treeview的AfterSelect函数的时候,单击同一节点多次无响应. 解决方法: 将首次单击的节点信息保存到selectTreeNode: 然后使用click函数,判断单击的节点是否和s ...

  6. HttpContext.Current.Session=null问题

    启用asp.net状态服务,可以让Session持久化!

  7. SDUT 1305 查找基因序列问题 dp

    题目: http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1305 这个题就是一个类似公共子串的dp ...

  8. hibernate配置文件详细解释

    <!--标准的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的编码方式--> <?xml version='1.0' ...

  9. 懒加载 jquery代码

    懒加载代码.据说这是jquery代码. 说白了就是在 开始的时候调用,这个和C#代码错误处理机制是一样的. function check() {          var obj = document ...

  10. c/c++ 传统数组的缺点

    专题:  动态内存分配 (所有高级语言,没有C里深刻) 传统数组的缺点: 1.数组长度必须事先指定,而且只能是常整数,不能是变量     例子 ]; //必须事先指定,而且只能是常整数 ; int a ...