经典算法之Kruskal算法
来源:互联网 发布:unix环境高级编程答案 编辑:程序博客网 时间:2024/06/06 16:47
/************************author's email:wardseptember@gmail.comdate:2017.12.13************************//*每次找出候选边中权值最小的边,就将该边并入生成树中。重复此过程直到所有边都被检测完。Kruskal算法的关键在于找出最小边和判断此最小边并入树是否形成回路。*/#include<iostream>#define INF 100//INF为比图中任何权值都大的数#define maxSize 6 //图的顶点数#define number 10 //图的边数using namespace std;typedef struct {//图的定义 float edges[maxSize][maxSize];//邻接矩阵的定义 int n, e; //分别为顶点数和边数}MGraph;MGraph createGraph(MGraph g);typedef struct { int a, b; //a和b为一条边所连的两个顶点 int weight; //边的权值}Road;int v[maxSize]; //定义并查集数组void createRoad(Road *road);//依照图构造各边int getRoot(int a); //在并查集中查找根的结点void bubbleSort(Road *road,int E); //依照各边的权值对各边进行冒泡排序,升序void Kruskal(MGraph g, int &sum, Road *road);//Kruskal算法int main() { Road road[number];//存放各边 /*初始化各边*/ for (int i = 0; i < 10; ++i) { road[i].weight = 0; road[i].a = 0; road[i].b = 0; } int sum ;//权值 MGraph g;//定义并初始化图g g.edges[maxSize][maxSize] = { 0 }; g.n = maxSize; g.e = 10; g = createGraph(g);//创建一个图 createRoad(road);//依照图构造各边 Kruskal(g, sum, road);//Kruskal算法 cout << "最小生成树的权值为:"; cout << sum << endl; return 0;}MGraph createGraph(MGraph g) {//此图的各个顶点为一个正无边形的顶点,加正中间一个点。正中间一个点与各个顶点相连 int i, j; for (i = 0; i < maxSize; i++) { for (j = 0; j < maxSize; j++) { g.edges[i][j] = INF; } } g.edges[0][1] = 6; g.edges[1][0] = 6; g.edges[0][2] = 1; g.edges[2][0] = 1; g.edges[0][3] = 5; g.edges[3][0] = 5; g.edges[1][2] = 4; g.edges[2][1] = 4; g.edges[1][4] = 3; g.edges[4][1] = 3; g.edges[2][3] = 2; g.edges[3][2] = 2; g.edges[2][4] = 7; g.edges[4][2] = 7; g.edges[2][5] = 8; g.edges[5][2] = 8; g.edges[3][5] = 9; g.edges[5][3] = 9; g.edges[4][5] = 11; g.edges[5][4] = 11; g.n = maxSize; g.e = 10; return g;}void createRoad(Road *road) {//依照图构造各边 road[0].a = 0; //顶点0 road[0].b = 1; //顶点1 road[0].weight = 6;//顶点0和顶点1之间的权值 road[1].a = 0; road[1].b = 2; road[1].weight = 1; road[2].a = 0; road[2].b = 3; road[2].weight = 5; road[3].a = 3; road[3].b = 2; road[3].weight = 2; road[4].a = 2; road[4].b = 1; road[4].weight = 4; road[5].a = 2; road[5].b = 5; road[5].weight = 8; road[6].a = 2; road[6].b = 4; road[6].weight = 7; road[7].a = 1; road[7].b = 4; road[7].weight = 3; road[8].a = 3; road[8].b = 5; road[8].weight = 9; road[9].a = 5; road[9].b = 4; road[9].weight = 11;}int getRoot(int a) { //在并查集中查找根的结点 while (a != v[a]) a = v[a]; return a;}void bubbleSort(Road *road, int E) {//依照各边的权值对各边进行冒泡排序,升序 int i, j, temp1,temp2,temp3, flag;/*temp1、temp2、temp3用于交换,flag用来标记是 否发生的了交换,没发生交换代表road已全部有序*/ /*冒泡排序*/ for (i = E - 1; i >= 1; --i) { flag = 0; for (j = 1; j <= i; ++j) { if (road[j - 1].weight > road[j].weight) { temp1 = road[j].weight; temp2 = road[j].a; temp3 = road[j].b; road[j].weight = road[j - 1].weight; road[j].a = road[j - 1].a; road[j].b = road[j - 1].b; road[j - 1].weight = temp1; road[j - 1].a = temp2; road[j - 1].b = temp3; flag = 1; } } if (flag == 0) break; }}void Kruskal(MGraph g, int &sum, Road *road) {//Kruskal算法 int i; int N, E, a, b; N = g.n;//图的顶点数 E = g.e;//图的边数 sum = 0; for (i = 0; i < N; ++i) v[i] = i; bubbleSort(road, E);//对road数组的E条边按其权值大小从小到大排序 /*下面这个循环求最小生成树的权值*/ for (i = 0; i < E; ++i) { a = getRoot(road[i].a); b = getRoot(road[i].b); if (a != b) {//没有形成回路,才并入最小生成树 v[a] = b; sum += road[i].weight;//求最小生成树的权值。这里可以进行输出或者其他操作 } }}
以上如有错误,请指出,大家共同学习进步。
阅读全文
0 0
- 经典算法之Kruskal算法
- 【经典算法】:图中的最小生成树算法之Prim算法和Kruskal算法
- 图之kruskal算法
- MST算法之Kruskal算法
- Kruskal算法之邻接矩阵实现
- Kruskal算法 之 Java详解
- 《大话数据结构》之Kruskal算法
- 图论之kruskal算法
- 项目 2 - 验证算法之Kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- kruskal算法
- Golang从入门到精通(十三):Golang复合数据之map
- 文章标题
- 变量、作用域、内存
- js生成日历
- PHP中使用OpenSSL生成证书及加密解密
- 经典算法之Kruskal算法
- Linux 下weka3.8中引用libsvm库
- 周志华机器学习 西瓜书(PDF) 斯坦福大学机器学习视频 机器学习基石+技法 邹博机器学习 七月在线机器学习 资源下载
- 关于Java面试,你应该准备这些知识点
- react-native 简天气——仅仅一个天气而已
- /与/* dispatcherservlet配置
- 谈谈单元测试之(二):测试工具 JUnit 3
- 最少拦截系统
- bzoj 2244: [SDOI2011]拦截导弹