Boruvka最小生成树代码
作者:互联网
1 // Boruvka's algorithm to find Minimum Spanning 2 // Tree of a given connected, undirected and 3 // weighted graph 4 #include <stdio.h> 5 6 // a structure to represent a weighted edge in graph 7 struct Edge 8 { 9 int src, dest, weight; 10 }; 11 12 // a structure to represent a connected, undirected 13 // and weighted graph as a collection of edges. 14 struct Graph 15 { 16 // V-> Number of vertices, E-> Number of edges 17 int V, E; 18 19 // graph is represented as an array of edges. 20 // Since the graph is undirected, the edge 21 // from src to dest is also edge from dest 22 // to src. Both are counted as 1 edge here. 23 Edge* edge; 24 }; 25 26 // A structure to represent a subset for union-find 27 struct subset 28 { 29 int parent; 30 int rank; 31 }; 32 33 // Function prototypes for union-find (These functions are defined 34 // after boruvkaMST() ) 35 int find(struct subset subsets[], int i); 36 void Union(struct subset subsets[], int x, int y); 37 38 // The main function for MST using Boruvka's algorithm 39 void boruvkaMST(struct Graph* graph) 40 { 41 // Get data of given graph 42 int V = graph->V, E = graph->E; 43 Edge *edge = graph->edge; 44 45 // Allocate memory for creating V subsets. 46 struct subset *subsets = new subset[V]; 47 48 // An array to store index of the cheapest edge of 49 // subset. The stored index for indexing array 'edge[]' 50 int *cheapest = new int[V]; 51 52 // Create V subsets with single elements 53 for (int v = 0; v < V; ++v) 54 { 55 subsets[v].parent = v; 56 subsets[v].rank = 0; 57 cheapest[v] = -1; 58 } 59 60 // Initially there are V different trees. 61 // Finally there will be one tree that will be MST 62 int numTrees = V; 63 int MSTweight = 0; 64 65 // Keep combining components (or sets) until all 66 // compnentes are not combined into single MST. 67 while (numTrees > 1) 68 { 69 // Everytime initialize cheapest array 70 for (int v = 0; v < V; ++v) 71 { 72 cheapest[v] = -1; 73 } 74 75 // Traverse through all edges and update 76 // cheapest of every component 77 for (int i=0; i<E; i++) 78 { 79 // Find components (or sets) of two corners 80 // of current edge 81 int set1 = find(subsets, edge[i].src); 82 int set2 = find(subsets, edge[i].dest); 83 84 // If two corners of current edge belong to 85 // same set, ignore current edge 86 if (set1 == set2) 87 continue; 88 89 // Else check if current edge is closer to previous 90 // cheapest edges of set1 and set2 91 else 92 { 93 if (cheapest[set1] == -1 || 94 edge[cheapest[set1]].weight > edge[i].weight) 95 cheapest[set1] = i; 96 97 if (cheapest[set2] == -1 || 98 edge[cheapest[set2]].weight > edge[i].weight) 99 cheapest[set2] = i; 100 } 101 } 102 103 // Consider the above picked cheapest edges and add them 104 // to MST 105 for (int i=0; i<V; i++) 106 { 107 // Check if cheapest for current set exists 108 if (cheapest[i] != -1) 109 { 110 int set1 = find(subsets, edge[cheapest[i]].src); 111 int set2 = find(subsets, edge[cheapest[i]].dest); 112 113 if (set1 == set2) 114 continue; 115 MSTweight += edge[cheapest[i]].weight; 116 printf("Edge %d-%d included in MST\n", 117 edge[cheapest[i]].src, edge[cheapest[i]].dest); 118 119 // Do a union of set1 and set2 and decrease number 120 // of trees 121 Union(subsets, set1, set2); 122 numTrees--; 123 } 124 } 125 } 126 127 printf("Weight of MST is %d\n", MSTweight); 128 return; 129 } 130 131 // Creates a graph with V vertices and E edges 132 struct Graph* createGraph(int V, int E) 133 { 134 Graph* graph = new Graph; 135 graph->V = V; 136 graph->E = E; 137 graph->edge = new Edge[E]; 138 return graph; 139 } 140 141 // A utility function to find set of an element i 142 // (uses path compression technique) 143 int find(struct subset subsets[], int i) 144 { 145 // find root and make root as parent of i 146 // (path compression) 147 if (subsets[i].parent != i) 148 subsets[i].parent = 149 find(subsets, subsets[i].parent); 150 151 return subsets[i].parent; 152 } 153 154 // A function that does union of two sets of x and y 155 // (uses union by rank) 156 void Union(struct subset subsets[], int x, int y) 157 { 158 int xroot = find(subsets, x); 159 int yroot = find(subsets, y); 160 161 // Attach smaller rank tree under root of high 162 // rank tree (Union by Rank) 163 if (subsets[xroot].rank < subsets[yroot].rank) 164 subsets[xroot].parent = yroot; 165 else if (subsets[xroot].rank > subsets[yroot].rank) 166 subsets[yroot].parent = xroot; 167 168 // If ranks are same, then make one as root and 169 // increment its rank by one 170 else 171 { 172 subsets[yroot].parent = xroot; 173 subsets[xroot].rank++; 174 } 175 } 176 177 // Driver program to test above functions 178 int main() 179 { 180 /* Let us create following weighted graph 181 10 182 0--------1 183 | \ | 184 6| 5\ |15 185 | \ | 186 2--------3 187 4 */ 188 int V = 4; // Number of vertices in graph 189 int E = 5; // Number of edges in graph 190 struct Graph* graph = createGraph(V, E); 191 192 193 // add edge 0-1 194 graph->edge[0].src = 0; 195 graph->edge[0].dest = 1; 196 graph->edge[0].weight = 10; 197 198 // add edge 0-2 199 graph->edge[1].src = 0; 200 graph->edge[1].dest = 2; 201 graph->edge[1].weight = 6; 202 203 // add edge 0-3 204 graph->edge[2].src = 0; 205 graph->edge[2].dest = 3; 206 graph->edge[2].weight = 5; 207 208 // add edge 1-3 209 graph->edge[3].src = 1; 210 graph->edge[3].dest = 3; 211 graph->edge[3].weight = 15; 212 213 // add edge 2-3 214 graph->edge[4].src = 2; 215 graph->edge[4].dest = 3; 216 graph->edge[4].weight = 4; 217 218 boruvkaMST(graph); 219 220 return 0; 221 } 222 223 // Thanks to Anukul Chand for modifying above code.
$g++ -std=c++11 -o main *.cpp
$main
Edge 0-3 included in MST Edge 0-1 included in MST Edge 2-3 included in MST Weight of MST is 19
标签:subsets,cheapest,int,graph,代码,最小,rank,edge,Boruvka 来源: https://www.cnblogs.com/hulianxingkong/p/15201779.html