Geeks : Kruskal’s Minimum Spanning Tree Algorithm 最小生成树

来源:互联网 发布:mix软件怎么用 编辑:程序博客网 时间:2024/05/22 03:03

寻找图中最小连通的路径,图如下:



算法步骤:

1. Sort all the edges in non-decreasing order of their weight.2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far. If cycle is not formed, include this edge. Else, discard it.  3. Repeat step#2 until there are (V-1) edges in the spanning tree.
关键是第二步难,这里使用Union Find来解决,可以几乎小于O(lgn)的时间效率来判断是否需要判断的顶点和已经选择的顶点成环。

正因为这步,使得原本简单的贪心法,变得不那么简单了。

这样本算法的时间效率达到:max(O(ElogE) , O(ElogV))

原文参考:http://www.geeksforgeeks.org/greedy-algorithms-set-2-kruskals-minimum-spanning-tree-mst/

#pragma once#include <stdio.h>#include <stdlib.h>#include <string.h>class KruskalsMST{struct Edge{int src, des, weight;};static int cmp(const void *a, const void *b){Edge *a1 = (Edge *) a, *b1 = (Edge *) b;return a1->weight - b1->weight;}struct Graph{int V, E;Edge *edges;Graph(int v, int e) : V(v), E(e){edges = new Edge[e];}virtual ~Graph(){if (edges) delete [] edges;}};struct SubSet{int parent, rank;};int find(SubSet *subs, int i){if (subs[i].parent != i)subs[i].parent = find(subs, subs[i].parent);return subs[i].parent;}void UnionTwo(SubSet *subs, int x, int y){int xroot = find(subs, x);int yroot = find(subs, y);if (subs[xroot].rank < subs[yroot].rank)subs[xroot].parent = yroot;else if (subs[xroot].rank > subs[yroot].rank)subs[yroot].parent = xroot;else{subs[xroot].rank++;subs[yroot].parent = xroot;}}Graph *graph;Edge *res;SubSet *subs;void initSubSet(){subs = new SubSet[graph->V];for (int i = 0; i < graph->V; i++){subs[i].parent = i;subs[i].rank = 0;}}void mst(){res = new Edge[graph->V-1];qsort(graph->edges, graph->E, sizeof(graph->edges[0]), cmp);initSubSet();for (int e = 0, i = 0; e < graph->V - 1 && i < graph->E; i++){Edge nextEdge = graph->edges[i];int x = find(subs, nextEdge.src);int y = find(subs, nextEdge.des);if (x != y){res[e++] = nextEdge;UnionTwo(subs, x, y);}}}void printResult(){printf("Following are the edges in the constructed MST\n");for (int i = 0; i < graph->V-1; ++i)printf("%d -- %d == %d\n", res[i].src, res[i].des, res[i].weight);}public:KruskalsMST(){/* Let us create following weighted graph100--------1|  \     |6|   5\   |15|      \ |2--------34       */int V = 4;  // Number of vertices in graphint E = 5;  // Number of edges in graphgraph = new Graph(V, E);// add edge 0-1graph->edges[0].src = 0;graph->edges[0].des = 1;graph->edges[0].weight = 10;// add edges 0-2graph->edges[1].src = 0;graph->edges[1].des = 2;graph->edges[1].weight = 6;// add edges 0-3graph->edges[2].src = 0;graph->edges[2].des = 3;graph->edges[2].weight = 5;// add edges 1-3graph->edges[3].src = 1;graph->edges[3].des = 3;graph->edges[3].weight = 15;// add edges 2-3graph->edges[4].src = 2;graph->edges[4].des = 3;graph->edges[4].weight = 4;mst();printResult();}~KruskalsMST(){if (res) delete [] res;if (subs) delete [] subs;if (graph) delete graph;}};



1 0
原创粉丝点击