克鲁斯卡尔(Kruskal)算法
# include <stdio.h> # define MAX_VERTEXES //最大顶点数
# define MAXEDGE //边集数组最大值
# define INFINITY //代表不可能的数(无穷大) typedef struct
{//图 结构体定义
int arc[MAX_VERTEXES][MAX_VERTEXES];//二位数组 矩阵
int numVertexes, numEdges;//当前图中的顶点数和边数 }MGraph; typedef struct
{//边集数组 结构体定义
int begin;
int end;
int weight; }Edge; void CreateMGraph (MGraph *G)
{//创建
int i, j;
//下面是已经输入好的
G->numVertexes = ;
G->numEdges = ; for (i=; i<G->numVertexes; i++)
for (j=; j<G->numVertexes; j++)
if (i == j)
G->arc[i][j] = ;
else
G->arc[i][j] = G->arc[j][i] = INFINITY; G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; for (i=; i<G->numVertexes; i++)
for (j=i+; j<G->numVertexes; j++)//矩阵的上三角,然后对称矩阵的下三角
G->arc[j][i] = G->arc[i][j];//对称
} void swapn (Edge *edges, int i, int j)
{//交换权值
int temp; //起始
temp = edges[i].begin;
edges[i].begin = edges[j].begin;
edges[j].begin = temp; //结束
temp = edges[i].end;
edges[i].end = edges[j].end;
edges[j].end = temp; //权值
temp = edges[i].weight;
edges[i].weight = edges[j].weight;
edges[j].weight = temp; return ;
} void sort (Edge edges[], MGraph *G)
{//对权值进行排序
int i, j;
for (i=; i<G->numEdges; i++)
for (j=i+; j<G->numEdges; j++)//对存入有效边(两端点的权值)进行冒泡排序
if (edges[i].weight > edges[j].weight)
swapn (edges, i, j);//交换权值 printf ("排序过后:\n");
for (i=; i<G->numEdges; i++)
printf ("边:(%d,%d) 权值:%d\n", edges[i].begin, edges[i].end, edges[i].weight); return ;
} int Find (int *parent, int f)//★
{// 查找连线顶点的尾部下标
//走过的路都有记录,如果走已经走过的路的话,那么返回的值(n=m);
while (parent[f] > )
f = parent[f];
return f;
} void MiniSpanTree_Kruskal (MGraph G)
{//克鲁斯卡尔算法
int i, j, n, m;
int k = ;
int parent[MAX_VERTEXES];//定义一维数组判断是否形成环路
Edge edges[MAXEDGE];//定义边集数组 for (i=; i<G.numVertexes; i++)//存储有效的边(两个端点和权值)
for (j=i+; j<G.numVertexes; j++)//矩阵上三角进行比较,因为对称,所以比较一半更节约时间
if (G.arc[i][j] < INFINITY)
{
edges[k].begin = i;
edges[k].end = j;
edges[k ++].weight = G.arc[i][j];
}
sort(edges, &G);//排序 for (i=; i<G.numVertexes; i++)
parent[i] = ; printf ("\n打印最小生成树:\n");
for (i=; i<G.numEdges; i++)
{
n = Find (parent, edges[i].begin);//★
m = Find (parent, edges[i].end);//★
if (n != m)
{
parent[n] = m;
printf ("边(%d,%d) 权值:%d\n", edges[i].begin, edges[i].end, edges[i].weight);
}
}
} int main (void) {
MGraph G;
CreateMGraph (&G);//创建
MiniSpanTree_Kruskal (G);//克鲁斯卡尔 算法 return ;
} /*
在vc++6.0运行结果: 排序过后:
边:(4,7) 权值:7
边:(2,8) 权值:8
边:(0,1) 权值:10
边:(0,5) 权值:11
边:(1,8) 权值:12
边:(3,7) 权值:16
边:(1,6) 权值:16
边:(5,6) 权值:17
边:(1,2) 权值:18
边:(6,7) 权值:19
边:(3,4) 权值:20
边:(3,8) 权值:21
边:(2,3) 权值:22
边:(3,6) 权值:24
边:(4,5) 权值:26 打印最小生成树:
边(4,7) 权值:7
边(2,8) 权值:8
边(0,1) 权值:10
边(0,5) 权值:11
边(1,8) 权值:12
边(3,7) 权值:16
边(1,6) 权值:16
边(6,7) 权值:19
Press any key to continue
*/
克鲁斯卡尔(Kruskal)算法的更多相关文章
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- 洛谷P3366【模板】最小生成树-克鲁斯卡尔Kruskal算法详解附赠习题
链接 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边.(N<=5000,M&l ...
- 图解最小生成树 - 克鲁斯卡尔(Kruskal)算法
我们在前面讲过的<克里姆算法>是以某个顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树的.同样的思路,我们也可以直接就以边为目标去构建,因为权值为边上,直接找最小权值的边来构建生成树 ...
- 克鲁斯卡尔(Kruskal)算法求最小生成树
/* *Kruskal算法求MST */ #include <iostream> #include <cstdio> #include <cstring> #inc ...
- 最小生成树——Kruskal(克鲁斯卡尔)算法
[0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 Kruskal(克鲁斯卡尔)算法 的idea 并用 源代码加以实现: 0.2)最小生成树的基础知识,参见 ...
- 经典问题----最小生成树(kruskal克鲁斯卡尔贪心算法)
题目简述:假如有一个无向连通图,有n个顶点,有许多(带有权值即长度)边,让你用在其中选n-1条边把这n个顶点连起来,不漏掉任何一个点,然后这n-1条边的权值总和最小,就是最小生成树了,注意,不可绕成圈 ...
- 最小生成树之克鲁斯卡尔(kruskal)算法
#include <iostream> #include <string> using namespace std; typedef struct MGraph{ string ...
- 数据结构与算法——克鲁斯卡尔(Kruskal)算法
目录 应用场景-公交站问题 克鲁斯卡尔算法介绍 克鲁斯卡尔算法图解 克鲁斯卡尔算法分析 如何判断回路? 代码实现 无向图构建 克鲁斯卡尔算法实现 获取一个点的终点解释 应用场景-公交站问题 某城市新增 ...
- 图->连通性->最小生成树(克鲁斯卡尔算法)
文字描述 上一篇博客介绍了最小生成树(普里姆算法),知道了普里姆算法求最小生成树的时间复杂度为n^2, 就是说复杂度与顶点数无关,而与弧的数量没有关系: 而用克鲁斯卡尔(Kruskal)算法求最小生成 ...
随机推荐
- Ubuntu12.04 LTS Add Sources List
1. First Step: sudo gedit /etc/apt/sources.list 2. Add Soures List Content: # deb cdrom:[Ubuntu LTS ...
- android---EditText黄色边框
http://liuzhichao.com/p/612.html 自定义android控件EditText边框背景 柳志超博客 » Program » Andriod » 自定义android控件Ed ...
- 一道C语言面试题:写一个宏,将16位的整数转为Big Endian
题目:输入16位整数x,如0x1234,将其转为Big Endian格式再输出,此例为输出 0x3412 来源:某500强企业面试题目 思路:将x左移8位得到a,将x右移8位得到b,a+b即为所得 / ...
- QT:轻松获取网页源码
获取网页源码的小例子,代码很简单,就不多作解释了. 不过一定要注意网页的编码问题,否则会出现乱码的!!! #include <QtCore> #include <QtNetwork& ...
- 非自定义和自定义Dialog的介绍!!!
一.非自定义Dialog的几种形式介绍 转自:http://www.kwstu.com/ArticleView/kwstu_20139682354515 前言 对话框对于应用也是必不可少的一个组件,在 ...
- 北京西服定做_衬衫定制_关于我们_Dimoon TLR.
北京西服定做_衬衫定制_关于我们_Dimoon TLR.
- hdu 1978 How many ways(dp)
Problem Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标 ...
- TransactionScope使用说明 【转】
TransactionScope是.Net Framework 2.0滞后,新增了一个名称空间.它的用途是为数据库访问提供了一个“轻量级”[区别于:SqlTransaction]的事物.使用之前必须添 ...
- 黑马程序员 Java基础<九>---> 多线程
ASP.Net+Android+IOS开发..Net培训.期待与您交流! 多线程 一.概述: 1.线程是什么 说到线程,我们就得先说说进程.所谓进程,就是一个正在执行(进行)中的程序,每一个进程执行都 ...
- ASP.NET之自定义异步HTTP处理程序(图文教程)
前面我们学习了关于关于自定义同步HTTP处理程序,相信大家可能感觉有所成就,但是这种同步的机制只能对付客户访问较少的情况或者数据处理量不大的情况,而今天这篇文章就是解决同步HTTP处理程序的这个致命缺 ...