Kruskal算法构造最小生成树
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算法构造最小生成树的更多相关文章
- c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树
c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路 ...
- c/c++ 用普利姆(prim)算法构造最小生成树
c/c++ 用普利姆(prim)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路.这时 ...
- 图的建立(邻接矩阵)+深度优先遍历+广度优先遍历+Prim算法构造最小生成树(Java语言描述)
主要参考资料:数据结构(C语言版)严蔚敏 ,http://blog.chinaunix.net/uid-25324849-id-2182922.html 代码测试通过. package 图的建 ...
- 利用Kruskal算法求最小生成树解决聪明的猴子问题 -- 数据结构
题目:聪明的猴子 链接:https://ac.nowcoder.com/acm/problem/19964 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个 ...
- kruskal算法求最小生成树(jungle roads的kruskal解法)
注意: 注意数组越界问题(提交出现runtimeError代表数组越界) 刚开始提交的时候,边集中边的数目和点集中点的数目用的同一个宏定义,但是宏定义是按照点的最大数定义的,所以提交的时候出现了数组越 ...
- 克鲁斯卡尔(Kruskal)算法求最小生成树
/* *Kruskal算法求MST */ #include <iostream> #include <cstdio> #include <cstring> #inc ...
- Prim算法、Kruskal算法和最小生成树 | Minimum Spanning Tree
graph to tree非常有趣! 距离的度量会极大地影响后续的分析,欧式距离会放大差异,相关性会缩小差异,导致某些细胞群分不开. 先直观看一下,第一个是Prim,第二个是Kruskal.但是肯定都 ...
- Kruskal算法:最小生成树
//Kruskal算法按照边的权值从小到大查看一遍,如果不产生圈(重边等也算在内),就把当前这条表加入到生成树中. //如果判断是否产生圈.假设现在要把连接顶点u和顶点v的边e加入生成树中.如果加入之 ...
- Prim算法和Kruskal算法求最小生成树
Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...
随机推荐
- 【ADO.NET】5、手机归属地查询( winfrom )
using System.IO; 有一个数据库手机号码的txt文件,格式是 : 13500000000-13560000000-中国移动 查询结果: 湖南移动[邵阳]文件夹选择对话框 FolderBr ...
- 【实习记】2014-08-27堆排序理解总结+使用typedef指代函数指针
过程记录 4个月前C语言版的七大排序算法实践让我在写C++版时轻车熟路.特别是冒泡,插入,希尔,选择这四种排序不用调试即运行成功.输出的效果与C语言做的版本完全一样,其中令我印象深刻的是,co ...
- html5生成柱状图(条形图)
<html> <canvas id="a_canvas" width="1000" height="700">< ...
- "position:relative"在IE中的Bug
当子元素过高导致父元素出现滚动条时,它并不会像预期的那样呆在父元素里,而是浮在父元素之上,并且位置不随滚动条的移动而改变.根源就是子元素的"position:relative".目 ...
- js 遍历json对象
//方法一: var data=[{name:"a",age:12},{name:"b",age:11},{name:"c",age:13} ...
- #Leet Code# Populating Next Right Pointers in Each Node II
描述:注意需要先self.connect(right)再self.connect(left),否则会有case通不过,原因是左边递归执行时依赖与右边的next已经建立,而先执行connect(left ...
- 用Eclipse 开发Dynamic Web Project应用程序 【转】
简介:本文仅简单介绍基于Eclipse开发Dynamic Web Project应用下的JSP,Servlet及TOMCAT数据源的配置和开发. 软件环境: Eclipse Java EE IDE f ...
- 定位 - CoreLocation - 区域报警
#import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewCont ...
- Cloud Insight!StatsD 系监控产品新宠!
年关将至,Cloud Insight 正式版悄然上线了.没有大张旗鼓的宣传,也没有热热闹闹的庆祝,只是一群人在上线前踏踏实实的优化了两周,然后发版,就是这样一件简单的事. 然而就是这样一个低调的产品, ...
- 【UVA 11183】 Teen Girl Squad (定根MDST)
[题意] 输入三元组(X,Y,C),有向图,定根0,输出MDST. InputThe first line of input gives the number of cases, N (N < ...