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. centos 6.5 安装jenkins

    Installation sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.rep ...

  2. 比较全面的gdb调试命令

    from:http://blog.csdn.net/xiajun07061225/article/details/8960332 http://blog.csdn.net/cjfeii/article ...

  3. php 文件路径设置 set_include_path(); get_include_path();

    <?php set_include_path($string); //设置路径 get_include_path(); // 获取当前的路径 //例如:文件路径为: //D:/phpweb/de ...

  4. CSS3 skew倾斜、rotate旋转动画

    css3出现之前,我们实现一个对象的一组连续动画需要通过JavaScript或Jquery编写,脚本代码较为复杂: 若需要实现倾斜.旋转之类的动画难度将更高(我还没试过用JavaScript或Jque ...

  5. nslookup命令详解

    Nslookup 是一个监测网络中DNS服务器是否能正确实现域名解析的命令行工具.它在 Windows NT/2000/XP(在之后的windows系统也都可以用的,比如win7,win8等) 中均可 ...

  6. 2016030208 - sql50题练习题

    数据库建表脚本和使用的数据请参考:http://www.cnblogs.com/zhtzyh2012/p/5235826.html sql50题练习参看:http://blog.sina.com.cn ...

  7. 实际中理解div布局和浮动

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. 有很多功能交给IIS实现就好了啊,之前干嘛要自己写?

    比方说设置默认主页啊,错误页伪静态之类的

  9. XE5 安装破解

    以下转载自:  盒子 不可以将本破解补丁分享到国外网站.论坛中!低调啊! 本破解补丁只适合中国大陆地区的Delphi.C++Builder爱好者和开发者! 本破解补丁只可用于个人研究交流使用,不得做商 ...

  10. bzoj 1200: [HNOI2005]木梳 DP

    1200: [HNOI2005]木梳 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 266  Solved: 125[Submit][Status] ...