kruskal算法是一个贪心算法,把所有的边按权值从小到大依次考虑,如果当前边加进生成树中会出现回路,则丢弃当前边,否则添加当前边。
克鲁斯卡尔算法(Kruskal‘s algorithm)是两个经典的最小生成树算法的较为简单理解的一个。这里面充分体现了贪心算法的精髓。大致的流程可以用一个图来表示。这里的图的选择借用了Wikipedia上的那个。非常清晰且直观。
首先第一步,我们有一张图,有若干点和边
第一步我们要做的事情就是将所有的边的长度排序,用排序的结果作为我们选择边的依据。这里再次体现了贪心算法的思想。资源排序,对局部最优的资源进行选择。
排序完成后,我们率先选择了边AD。这样我们的图就变成了
#include <iostream> #include <algorithm> using namespace std; const int mxsz = 1000; struct Edge{ int st, ed, len; } edge[mxsz];
bool cmp(const Edge &a, const Edge &b) { return a.len < b.len; } void Kruskal() { //输入图 int nodeNum, edgeNum; //节点数量、边的数量 scanf("%d%d", &nodeNum, &edgeNum); for (int i = 0; i < edgeNum; i++) //输入边 { int st, ed, len; scanf("%d%d%d", &st, &ed, &len); edge[i].st = st, edge[i].ed = ed, edge[i].len = len; } //计算最小生成树权值 sort(edge, edge + edgeNum, cmp); //边排序 n = nodeNum; makeSet(); //初始化 int weight = 0; for (int i = 0; i < edgeNum; i++) //遍历边 if (unionSet(edge[i].st, edge[i].ed) == 1) //合并边的两个节点所在集合 weight += edge[i].len; //如果节点集合不同,加入最小生成树中 printf("最小生成树权值:%d\n", weight); }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/djd1234567/article/details/48058465