一、最小生成树(MST)

  ①、生成树的代价:设G=(V,E)是一个无向连通网,生成树上各边的权值之和称为该生成树的代价。

  ②、最小生成树:在图G所有生成树中,代价最小的生成树称为最小生成树。

  最小生成树的概念可以应用到许多实际问题中。 例:在n个城市之间建造通信网络,至少要架设n-1条通信线路,而每两个城市之间架设通信线路的造价是不一样的,那么如何设计才能使得总造价最小?

  ③、MST性质:假设G=(V, E)是一个无向连通网,U是顶点集V的一个非空子集。若(u, v)是一条具有最小权值的边,其中u∈U,v∈V-U,则必存在一棵包含边(u, v)的最小生成树。

二、Prim算法

  ①基本思想:设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是G的最小生成树, T的初始状态为U={u0}(u0∈V),TE={ },重复执行下述操作:在所有u∈U,v∈V-U的边中找一条代价最小的边(u, v)并入集合TE,同时v并入U,直至U=V。

  关键:是如何找到连接U和V-U的最短边,利用MST性质,可以用下述方法构造候选最短边集:对应V-U中的每个顶点,保留从该顶点到U中的各顶点的最短边。

  ②数据结构设计

  数组lowcost[n]:用来保存集合V-U中各顶点与集合U中顶点最短边的权值,lowcost[v]=0表示顶点v已加入最小生成树中;

  数组adjvex[n]:用来保存依附于该边(集合V-U中各顶点与集合U中顶点的最短边)在集合U中的顶点。

  如何用数组lowcost和adjvex表示候选最短边集?

  lowcost[i]=w;表示顶点vi和顶点vk之间的权值为w,

  adjvex[i]=k;其中:vi∈ V-U 且vk ∈U。

  ③Prim算法——伪代码

. 初始化两个辅助数组lowcost和adjvex;
. 输出顶点u0,将顶点u0加入集合U中;
. 重复执行下列操作n-1次
3.1 在lowcost中选取最短边,取adjvex中对应的顶点序号k;
3.2 输出顶点k和对应的权值;
3.3 将顶点k加入集合U中;
3.4 调整数组lowcost和adjvex;

  ④C++实现

 #include<iostream>
#include<fstream>
using namespace std; #define MAX 100
#define MAXCOST 0x7fffffff int graph[MAX][MAX]; /*方法二*/
struct Node
{
int lowcost;// 权值
int adjvex;// 候选最短边的邻接点
};
Node shortEdge[MAX];// 候选最短边集合
void prim2(int graph[][MAX], int n)
{
// 初始化辅助数组shortEdge,所有点到点1的权值
for (int i = ; i <= n; i++)
{
shortEdge[i].lowcost = graph[][i];
shortEdge[i].adjvex = ;
}
shortEdge[].lowcost = ;// 将顶点1加入集合U
for (int i = ; i <= n; i++)
{
// 寻找最短边的邻接点k
int k = , min = MAXCOST;
for (int j = ; j <= n; j++)
{
if (min >shortEdge[j].lowcost&&shortEdge[j].lowcost!=)
{
min = shortEdge[j].lowcost;
k = j;
}
}
cout << "(" << k << shortEdge[k].adjvex << ")" << shortEdge[k].lowcost;
shortEdge[k].lowcost = ;// 将顶点k加入结合U中
for (int j = ; j <= n; j++)
{
if (graph[k][j] < shortEdge[j].lowcost)
{
shortEdge[j].lowcost = graph[k][j];
shortEdge[j].adjvex = k;
}
}
}
} int main()
{
int i, j, k, m, n;
int x, y, cost;
ifstream in("input.txt");
in >> m >> n;//m=顶点的个数,n=边的个数
//初始化图G
for (i = ; i <= m; i++)
{
for (j = ; j <= m; j++)
{
graph[i][j] = MAXCOST;
}
}
//构建图G
for (k = ; k <= n; k++)
{
in >> i >> j >> cost;
graph[i][j] = cost;
graph[j][i] = cost;
}
prim2(graph, m);
system("pause");
return ;
}

三、Kruskal算法

  ①基本思想:设无向连通网为G=(V, E),令G的最小生成树为T=(U, TE),其初态为U=V,TE={ },然后,按照边的权值由小到大的顺序,考察G的边集E中的各条边。若被考察的边的两个顶点属于T的两个不同的连通分量,则将此边作为最小生成树的边加入到T中,同时把两个连通分量连接为一个连通分量;若被考察边的两个顶点属于同一个连通分量,则舍去此边,以免造成回路,如此下去,当T中的连通分量个数为1时,此连通分量便为G的一棵最小生成树。

  ②数据结构设计:因为Kruskal算法是依次对图中的边进行操作,因此考虑用边集数组存储图中的边,为了提高查找最短边的速度,可以先对边集数组按边上的权值排序。

 struct EdgeType
{
int from, to;// 边依附的两个顶点
int weight;// 边的权值
}; template<class T>
struct EdgeGraph
{
T vertex[Maxvertex];// 存放顶点信息
vector<EdgeType> edge;// 存放边的数组(用vector便于排序)
int vertexNum, edgeNum;//顶点数和边数
};

  ③Kruskal算法——伪代码

. 初始化:U=V;  TE={ };
. 循环直到T中的连通分量个数为1
2.1 在E中寻找最短边(u,v);
2.2 如果顶点u、v位于T的两个不同连通分量,则
2.2. 将边(u,v)并入TE;
2.2. 将这两个连通分量合为一个;
2.3 在E中标记边(u,v),使得(u,v)不参加后续最短边的选取;

  ④C++实现

#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std; const int Maxvertex = ;// 最多顶点数
const int MaxEdge = ;// 最多边数 struct EdgeType
{
int from, to;// 边依附的两个顶点
int weight;// 边的权值
}; template<class T>
struct EdgeGraph
{
T vertex[Maxvertex];// 存放顶点信息
vector<EdgeType> edge;// 存放边的数组(用vector便于排序)
int vertexNum, edgeNum;//顶点数和边数
};
int FindRoot(int parent[], int v)// 求顶点的双亲结点
{
int t = v;
while(parent[t]> -)
t = parent[t];
return t;
}
void Kruskal(EdgeGraph<int> G)
{
int parent[Maxvertex];
for (int i = ; i < G.vertexNum; i++)
parent[i] = -;// 表示顶点i没有双亲结点
for (int num = , i = ; i < G.edgeNum; i++)
{
int vex1 = FindRoot(parent, G.edge[i].from);
int vex2 = FindRoot(parent, G.edge[i].to);
if (vex1 != vex2)
{
cout << "(" << G.edge[i].from << G.edge[i].to << ")" << endl;
parent[vex2] = vex1;// 合并生成树
num++;
if (num == G.vertexNum - )
return;
}
} } bool sort_by_weight(EdgeType&k1, EdgeType&k2)
{
return k1.weight < k2.weight;
}
int main()
{
EdgeGraph<int> Edgraph;// 存放图的信息
ifstream in("input.txt");
in >> Edgraph.vertexNum >> Edgraph.edgeNum;
//构建图G
for (int k = ; k <Edgraph.edgeNum; k++)
{
EdgeType temp;
in >> temp.from >> temp.to >> temp.weight;
Edgraph.edge.push_back(temp);
}
// 将边按照权值排序
sort(Edgraph.edge.begin(), Edgraph.edge.end(), sort_by_weight);
Kruskal(Edgraph);
system("pause");
return ;
}
input.txt

最小生成树-Prim算法与Kruskal算法的更多相关文章

  1. 转载:最小生成树-Prim算法和Kruskal算法

    本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...

  2. 最小生成树Prim算法和Kruskal算法

    Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...

  3. 最小生成树---Prim算法和Kruskal算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

  4. 最小生成树——Prim算法和Kruskal算法

    洛谷P3366 最小生成树板子题 这篇博客介绍两个算法:Prim算法和Kruskal算法,两个算法各有优劣 一般来说当图比较稀疏的时候,Kruskal算法比较快 而当图很密集,Prim算法就大显身手了 ...

  5. 最小生成树Prim算法和Kruskal算法(转)

    (转自这位大佬的博客 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html ) Prim算法 1.概览 普里姆算法(Pr ...

  6. hdu1233 最小生成树Prim算法和Kruskal算法

    Prim算法 时间复杂度:O(\(N^2\),N为结点数) 说明:先任意找一个点标记,然后每次找一条最短的两端分别为标记和未标记的边加进来,再把未标记的点标记上.即每次加入一条合法的最短的边,每次扩展 ...

  7. 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

    最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...

  8. 最小生成树之Prim算法,Kruskal算法

    Prim算法 1 .概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gr ...

  9. C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)

    1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...

  10. 最小生成树之Prim算法和Kruskal算法

    最小生成树算法 一个连通图可能有多棵生成树,而最小生成树是一副连通加权无向图中一颗权值最小的生成树,它可以根据Prim算法和Kruskal算法得出,这两个算法分别从点和边的角度来解决. Prim算法 ...

随机推荐

  1. lua默认是double类型

    把c#的float类型传给lua  ,lua自己换转成double ,一转就出精度问题 lua只有double没有float ===================================== ...

  2. 游戏开发者注意!这个音频SDK可以完美兼容所有主流游戏引擎

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯游戏云 发表于云+社区专栏 在网络游戏中,无论是大逃杀.棋牌类.电子竞技类还是娱乐休闲类小游戏,玩家和玩家之间的互动.语音聊天是一 ...

  3. 利用Map解决复杂业务

    遍历出题库表的题库名称和题库id,根据题目id即questionBankId获取 分组,即该题库题目总数,该题库题目正确数,该题库已回答题目数. <sqltemplate id="co ...

  4. vue加载Element ui地址省市区插件-- element-china-area-data

    1.安装 npm install element-china-area-data -S 2.使用(引入) import { provinceAndCityData, regionData, provi ...

  5. C#基础笔记 转自wojiushigelg

    笔记如下: 概念:.net与c# .net/dontnet:一般指.net framework框架,一种平台,一种技术 c#(charp):一种编程语言,可以开发基于.net的应用. *java既是一 ...

  6. .Net Core GB2312编码问题

    1.今天抓取了一个网页的源代码.发现中文是乱码的,马上第一反应是编码问题..... 2.仔细一看基于WebClient写的代码,还真的是没有设置编码... /// <summary> // ...

  7. 解决github无法访问的问题

     gitbub是外网,经常会遇到访问不了的问题,并且有时能访问也网速好慢. 解决这个问题的方法是 更改hosts文件,地址: C:\Windows\System32\Drivers\etc 我在hos ...

  8. 在 Azure 上创建和链接 Azure SQL 数据库

    本快速入门介绍了如何在 Azure 门户中创建并连接 Azure SQL 数据库.在本教程中完成的所有操作均符合 1 元试用条件. 开始之前 如果您还没有 Azure 账户,可以申请 1 元试用账户. ...

  9. Oracle 数据库字典 sys.col$ 表中关于type#的解释

    sys.col$ 表是oracle基础数据字典表中的列表,表中描述了数据库中各列信息,其中type#是列的数据类型.以下表格说明了各个数值的含义,以供参考. 值 说明 1 如果列 charsetfor ...

  10. 点击空白处--某个div 消失

    背景:1.需要在 easyui grid 的编辑框 获取焦点的时候,在正下方展示费用类型的网格 2.在点击费用类型网格以外的地方,该网格消失 思路: 一.用easyui 的panel 作为费用类型网格 ...