实现Prim算法,需设置两个辅助一维数组lowcost和closevertex。

  1. 其中lowcost用来保存集合V-U中各顶点与集合U中各顶点构成的边中具有最小权值的边的权值;
  2. 数组closevertex用来保存依附于该边的在集合U中的顶点。

过程:
假设初始状态时,U={u0}(u0为出发的顶点),这时有lowcost[0]=0,它表示顶点u0已加入集合U中,数组lowcost的其他各分量的值是顶点u0到其余各顶点所构成的直接边的权值。
然后不断选取权值最小的边(ui,uk)(ui∈U,uk∈V-U),每选取一条边,就将lowcost(k)置为0,表示顶点uk已加入集合U中。
由于顶点uk从集合V-U进入集合U后,这两个集合的内容发生了变化,就需依据具体情况更新数组lowcost和closevertex中部分分量的内容。
最后closevertex中即为所建立的最小生成树。

当无向网采用二维数组存储的邻接矩阵存储时,Prim算法的C++实现算法如下:

void MGraph::Min_Tree_Prim(int u)
{for (int i = 0; i < vertexnum; i++)if (i != u){close_edge[i].adjvertex = u;close_edge[i].lowcost = arcs[u][i];}close_edge[u].lowcost = 0;int k;for (int i = 0; i < vertexnum - 1; i++){int w = MAXW;for (int j = 0; j < vertexnum; j++){if (close_edge[j].lowcost != 0 && close_edge[j].lowcost < w){w = close_edge[j].lowcost;k = j;}}close_edge[k].lowcost = 0;for (int j = 0;j<vertexnum;j++)if (arcs[k][j] < close_edge[j].lowcost){close_edge[j].adjvertex = k;close_edge[j].lowcost = arcs[k][j];}}for (int i = 0; i < vertexnum; i++)if (i != u)cout << i << "->" << close_edge[i].adjvertex << "," << arcs[i][close_edge[i].adjvertex] << endl;
}

完整代码如下:

#include <iostream>
#include <queue>
using namespace std;
typedef int VertexType;
typedef int EdgeType;
const int MaxVertexNum = 30;
const int MAXW = 1e8;class closEdge
{friend class MGraph;
private:int adjvertex;int lowcost;
};class MGraph
{public:MGraph(){CreatGraph();};void Min_Tree_Prim(int u);void CreatGraph();void Visit(int v);void BFS(int v);void BFStraverse();void DFStraverse();bool Ispath_BFS(int i, int j);//判断结点i和结点j之间是否有路径bool Ispath_DFS(int i, int j);//判断结点i和结点j之间是否有路径void Init_vis();
private:void DFS(int i, int j, bool &flag);void dfs_graph(int i);VertexType vertexs[MaxVertexNum];EdgeType arcs[MaxVertexNum][MaxVertexNum];int vertexnum;int edgenum;closEdge close_edge[MaxVertexNum];bool vis[MaxVertexNum];
};void MGraph::Min_Tree_Prim(int u)
{for (int i = 0; i < vertexnum; i++)if (i != u){close_edge[i].adjvertex = u;close_edge[i].lowcost = arcs[u][i];}close_edge[u].lowcost = 0;int k;for (int i = 0; i < vertexnum - 1; i++){int w = MAXW;for (int j = 0; j < vertexnum; j++){if (close_edge[j].lowcost != 0 && close_edge[j].lowcost < w){w = close_edge[j].lowcost;k = j;}}close_edge[k].lowcost = 0;for (int j = 0;j<vertexnum;j++)if (arcs[k][j] < close_edge[j].lowcost){close_edge[j].adjvertex = k;close_edge[j].lowcost = arcs[k][j];}}for (int i = 0; i < vertexnum; i++)if (i != u)cout << i << "->" << close_edge[i].adjvertex << "," << arcs[i][close_edge[i].adjvertex] << endl;
}void MGraph::CreatGraph()
{Init_vis();cout << "请输入图的顶点个数和边的条数" << endl;cin >> vertexnum >> edgenum;cout << "请依次输入按序号0到n顶点的中存储的信息" << endl;for (int i = 0; i < vertexnum; i++) cin >> vertexs[i];for (int i = 0; i < vertexnum; i++)for (int j = 0; j < vertexnum; j++)arcs[i][j] = MAXW;cout << "请输入边的信息(该图以有向图的邻接矩阵存储方式存储)" << endl;for (int i = 0; i < edgenum; i++){int a1, a2, w;cout << "输入边<i,j>对应的顶点序号i,j,然后再输入该边的权值" << endl;cin >> a1 >> a2>>w;arcs[a1][a2] = w;arcs[a2][a1] = w;}
}void MGraph::Init_vis()
{for (int i = 0; i < MaxVertexNum; i++) vis[i] = false;
}void MGraph::Visit(int v)
{cout << vertexs[v] << " ";
}void MGraph::BFS(int v)
{queue<int >q;q.push(v);vis[v] = true;while (q.size()){int t = q.front();Visit(t);q.pop();for (int i = 0; i < vertexnum; i++){if (arcs[t][i] == 1 && vis[i] == false){vis[i] = true;q.push(i);}}}cout << endl;Init_vis();
}void MGraph::BFStraverse()
{queue<int >q;for (int i = 0; i < vertexnum; i++){if (vis[i] == false){vis[i] = true;q.push(i);while (q.size()){int t = q.front();Visit(t);q.pop();for (int j = 0; j < vertexnum; j++)if (arcs[t][j] == 1 && vis[j] == false){vis[j] = true;q.push(j);}}}}cout << endl;Init_vis();
}void MGraph::dfs_graph(int i)
{Visit(i);for (int j = 0; j < vertexnum; j++){if (arcs[i][j] == 1 && vis[j] == false){vis[j] = true;dfs_graph(j);}}
}void MGraph::DFStraverse()
{for (int i = 0; i < vertexnum; i++){if (vis[i] == false){vis[i] = true;dfs_graph(i);}}cout << endl;Init_vis();
}bool MGraph::Ispath_BFS(int i, int j)
{queue<int >q;vis[i] = true;q.push(i);while (q.size()){int t = q.front();q.pop();if (t == j){Init_vis();return true;}for (int k = 0; k < vertexnum; k++){if (arcs[t][k] == 1 && vis[k] == false){vis[k] = true;q.push(k);}}}Init_vis();return false;
}void MGraph::DFS(int i, int j, bool &flag)
{if (i == j){flag = true;return;}for (int k = 0; k < vertexnum; k++){if (arcs[i][k] == 1 && vis[k] == false){vis[k] = true;DFS(k, j, flag);vis[k] = false;}}
}bool MGraph::Ispath_DFS(int i, int j)
{bool flag = false;vis[i] = true;DFS(i, j, flag);Init_vis();if (flag) return true;else return false;
}int main()
{MGraph g;int v;cin >> v;g.BFS(v);g.BFStraverse();g.DFStraverse();int n;cin >> n;g.Min_Tree_Prim(n);return 0;
}

测试结果:

C++ 实现无向图的最小生成树Prim算法(附完整代码)相关推荐

  1. 手撕代码之七大常用排序算法 | 附完整代码

    点击上方↑↑↑蓝字关注我们~ 「2019 Python开发者日」全日程揭晓,请扫码咨询 ↑↑↑ 0.导语 本节为手撕代码系列之第一弹,主要来手撕排序算法,主要包括以下几大排序算法: 直接插入排序 冒泡 ...

  2. OpenCV实现图像对齐ECC算法(附完整代码)

    OpenCV实现图像对齐ECC算法 OpenCV实现图像对齐ECC算法 OpenCV实现图像对齐ECC算法 #include <opencv2/imgcodecs.hpp> #includ ...

  3. OpenCV Gunnar Farneback的密集光流算法(附完整代码)

    OpenCV Gunnar Farneback的密集光流算法 OpenCV Gunnar Farneback的密集光流算法 OpenCV Gunnar Farneback的密集光流算法 #includ ...

  4. [Java学习] 最小生成树——Prim算法

    文章目录 最小生成树 Prim算法流程 应用实例 求最小生成树 最小生成树 百度百科上对于最小生成树的定义是这样的:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结 ...

  5. D-OJ刷题日记:使用邻接矩阵实现最小生成树Prim算法 题目编号:1135

    理解: [理解prim算法本质--让一棵小树逐渐长大] Prim算法:又称为加边法,即每次选择最小权值的边加入到生成树中,然后再更新权值,如此反复,保证每次最优来达到最优解. Prim算法生成树用的是 ...

  6. 西南科技大学OJ题 求最小生成树(Prim算法)1075

    求最小生成树(Prim算法) 1000(ms) 10000(kb) 2256 / 4495 Tags: 生成树 求出给定无向带权图的最小生成树.图的定点为字符型,权值为不超过100的整形.在提示中已经 ...

  7. 最小生成树-Prim算法详解(含全部代码)

    目录 适用条件 测试所用图 算法详解 Prim算法代码 全部代码 实验结果 适用条件 加权连通图 测试所用图 所用原图及生成过程 其中,(a) 为原图,圆圈里面是节点的名称,边上的数字是边的权值.由实 ...

  8. 最小生成树Prim算法Java版

    最小生成树Prim算法Java版 算法描述: 在一个加权连通图中,顶点集合V,边集合为E 任意选出一个点作为初始顶点,标记为visit,计算所有与之相连接的点的距离,选择距离最短的,标记visit. ...

  9. 最小生成树 - Prim算法

    最小生成树 - Prim算法 思路: 采用 贪心策略,每次选取连通块外延的最短边和对应的点放入连通块,再更新新的连通块外延的边.连通部分逐渐扩大,最后将整个图连通起来,并且边长之和最小. 时间复杂度: ...

最新文章

  1. .npy文件_python如何利用numpy存取文件
  2. 中国国际消费电子博览会拥抱转型,全新面貌拭目以待!
  3. 【玩转数据】让您的PPT数据图表炫酷起来吧!
  4. 上海交通大学python教材答案-上海交通大学python期末考试样题加解析.doc
  5. 关于BFD(双向转发检测)开发的总结
  6. 何洁音乐会今晚开唱 大手笔打造pure show
  7. [工作积累] shadow map问题汇总
  8. java打印三角形,菱形。任意边长大小
  9. 使用 NodeJS+Express+MySQL 实现简单的增删改查
  10. 【机器学习】高斯过程python包安装过程
  11. PHP 程序员危机:如何快速成长为不可或缺的技术人才?
  12. 部署django应用
  13. 在线程序员 计算器 (中文)
  14. 什么是TTL?标准USB接口是TTL吗?RS232、RS422、RS485的区别?
  15. Photoshop CC 2017 For Mac 安装与破解
  16. lanyu 激活idea2018.3.5
  17. 在oracle存储过程中创建临时表
  18. VRP和调度问题的主流精确算法和启发式算法
  19. 【大数据处理技术】实验4
  20. 该文件没有与之关联的应用...的解决方法

热门文章

  1. 学习C语言指针,这一篇案例教程就够够的了
  2. 【Python可视化】利用Numpy绘制各种统计图表
  3. AndroidStudio自定义属性xmlns无法识别问题解决in Gradle projects,always use http://schemas.android.com/apk/res-auto
  4. Android之ButterKnife--View注入框架
  5. 《看聊天记录都学不会C#?太菜了吧》(2)C#那么简单我为何之前还学C语言?
  6. 【二】Windows API 零门槛编程指南——CreateWindow 窗口创建 “万字长篇专业术语全解”
  7. cstring判断包含字符串_Python字符串方法之-解决判断问题
  8. 怎么计算信息完整度_德阳冻货运镖怎么计算费用
  9. 统信uos系统考试题_148款!富士通及旗下晟拓品牌系列打印机适配统信UOS
  10. c语言指针索引数组,C语言数组指针表示法