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. CodeFirst 的编程方式

    第一步:创建控制台项目第二步:添加新建项目→Ado.Net空实体模型第三步:添加实体:Customer,添加几个必要的测试字段第四步:添加实体之间的联系第五步:根据模型生成数据库脚本,并执行sql脚本 ...

  2. ORACLE数据库闪回日志写满

    网站页面无法显示完整.检查web服务是正常的,所以可能是ORACLE数据库出了问题. 首先检查闪回日志写满 然后检查归档日志文件写满的缘故了.使用以下几个命令可以看出当前归档日志文件的使用情况: se ...

  3. Windows7 下安装 CentOS6.5

    内容来自:http://blog.163.com/for_log/blog/static/2162830282013031031278/第一部分:安装前准备1. 准备两个fat32格式的分区,一个用于 ...

  4. 读取xml文件(可执行文件根目录debug)

    xml文件格式如下 <?xml version="1.0" encoding="utf-8" ?> <root> <appKey& ...

  5. Omnithreadlibary学习(1)-异步执行

    program main; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, OtlParallel; begin Parallel.Async( ...

  6. magento install

    1: apt-get insatll   apache2  mysql  php5 2: 把下载的magneto 解压后放到  /var/www/magento 3: 进入   http://127. ...

  7. POJ 1716 Integer Intervals 差分约束

    题目:http://poj.org/problem?id=1716 #include <stdio.h> #include <string.h> #include <ve ...

  8. c# .net使用SqlDataReader注意的几点

    转自:http://blog.knowsky.com/258608.htm 1.当SqlDataReader没有关闭之前,数据库连接会一直保持open状态,所以在使用SqlDataReader时,使用 ...

  9. 定位 - CoreLocation - 指南针

    #import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewCont ...

  10. 关于ADMM的研究(二)

    关于ADMM的研究(二) 4. Consensus and Sharing 本节讲述的两个优化问题,是非常常见的优化问题,也非常重要,我认为是ADMM算法通往并行和分布式计算的一个途径:consens ...