Before the Minimum Spanning Tree Prim algorithm is summarized, and gives the code implementation, see: http://www.cnblogs.com/dzkang2011/p/prim_1.html
I. Introduction
Due to busy with various transactions, learning about algorithms has stagnated. Now we will add another algorithm for finding the Minimum Spanning Tree, namely the Kruskal algorithm. For more information about the correctness of the Minimum Spanning Tree Algorithm, see the above link.
The Kruskal algorithm is a simple and easy-to-understand algorithm that provides excellent performance when the image is relatively sparse, however, when the image is dense (| E | >>| V |), the performance is inferior to that of the Prim algorithm. Later, we will analyze the time complexity of the Kruskal algorithm based on the actual code.
The Krusksl algorithm uses the parallel query set (expressed in the introduction to algorithms as non-intersecting sets. Initially, all our vertices constitute a separate tree, that is, a forest composed of | V | trees. The algorithm first needs to sort all edges in descending order according to the weight value. Then, select the edge based on the weight from small to large. If the two endpoints of the edge are not in a tree, merge them and place the edge in the minimal spanning tree. Until all edges are accessed. It can be seen that the Kruskal algorithm is a greedy algorithm and can find the global optimal solution. Algorithms are easy to understand. We do not provide proof. If you are interested, go to the introduction to algorithms.
2. pseudocode
The pseudo code of the algorithm is as follows, where A saves the Minimum Spanning Tree, MAKE-SET (v) indicates to construct A tree with only vertices v, FIND-SET (u) it indicates the root node of the tree where u is located, and Union (u, v) indicates the tree where u and v are merged:
MST-KRUSKAL (G, W)
A zookeeper
For each vertex v ε V [G]
Do MAKE-SET (v)
Sort the eages of E into nondecreasing order by weight w
For each eage (u, v) ε E, teken in nondecreasing order by weight
Do if (FIND-SET (u) =find-SET (v ))
Then A bought A packet {(u, v )}
Union (u, v)
Return
Iii. Implementation
The implementation of C ++ is given below, and then the time complexity is analyzed:
1 # include <iostream> 2 # include <cstdio> 3 # include <algorithm> 4 # include <cstring> 5 using namespace std; 6 7 # define maxn 110 // maximum number of vertices 8 int n, m; // Number of vertices, number of edges 9 int parent [maxn]; // Father's Day, when the value is-1, it indicates that the root node is 10 int ans; // It stores the structure with the minimum generated tree weight of 11 struct eage // side, and u and v are the two ends, w is the edge weight of 12 {13 int u, v, w; 14} EG [5010]; 15 16 bool cmp (eage a, eage B) // call 17 {18 return. w <B. w; 19} 20 21 int Find (int x) // search for the root node and determine whether the basis for the same tree is 22 {2 3 if (parent [x] =-1) return x; 24 return Find (parent [x]); 25} 26 27 void Kruskal () // Kruskal algorithm, parent can restore a spanning tree, or 28 {29 memset (parent,-1, sizeof (parent); 30 sort (EG + 1, EG + m + 1, cmp); // sort the edge from small to large by weight 31 ans = 0; 32 for (int I = 1; I <= m; I ++) // select edge 33 {34 int t1 = Find (EG [I]. u), t2 = Find (EG [I]. v); 35 if (t1! = T2) // select this edge if it is not in the same tree and combine the two trees 36 {37 ans + = EG [I]. w; 38 parent [t1] = t2; 39} 40} 41} 42 int main () 43 {44 while (~ Scanf ("% d", & n, & m) 45 {46 for (int I = 1; I <= m; I ++) 47 scanf ("% d", & EG [I]. u, & EG [I]. v, & EG [I]. w); 48 Kruskal (); 49 printf ("% d \ n", ans); 50} 51 return 0; 52}
Iv. Time Complexity
Analyze the time complexity of the Kruskal algorithm in the above Code. n is represented by V, and m is represented by E.:
Row 29: Set the parent nodes of vertices to-1 and the time to O (V)
Row 30: The sort function in stl. the header file is # include <algorithm>, and the time complexity is O (E log E)
32-40 rows: Because the FIND-SET operation is a tree search operation, the average time complexity is O (lg V), because the average time complexity of these rows is O (E log V)
In summary, the total complexity is represented as: O (V) + O (E log E) + O (E log V );
When the image is a dense image, the time complexity can be expressed as O (E log E );
A general graph is a sparse graph | E | <| V | ^ 2. the time complexity can be expressed as O (E log V ).
Therefore, in terms of time complexity, when the graph is a sparse graph, the Kruskal algorithm has the same performance as Prim. When the graph is a dense graph, Prim has better performance.
5. Tips
Note that each merge of two trees reduces the number of trees by 1. When there is only one root node, that is, only one tree, the Minimum Spanning Tree is generated and the program can be terminated, there is no need to view the edge with a higher weight. Therefore, to determine the number of root nodes, you can improve the performance when the graph is dense. The code is modified as follows, as shown in the complete figure:
1 # include <iostream> 2 # include <cstdio> 3 # include <algorithm> 4 # include <cstring> 5 using namespace std; 6 7 # define maxn 110 // maximum number of vertices 8 int n, m; // Number of vertices, number of edges 9 int parent [maxn]; // Father's Day, when the value is-1, it indicates that the root node is 10 int ans; // It stores the structure with the minimum generated tree weight of 11 struct eage // side, and u and v are the two ends, w is the edge weight of 12 {13 int u, v, w; 14} EG [5010]; 15 16 bool cmp (eage a, eage B) // call 17 {18 return. w <B. w; 19} 20 21 int Find (int x) // search for the root node and determine whether the basis for the same tree is 22 {2 3 if (parent [x] =-1) return x; 24 return Find (parent [x]); 25} 26 27 void Kruskal () // Kruskal algorithm, parent can restore a spanning tree, or forest 28 {29 memset (parent,-1, sizeof (parent); 30 int cnt = n; // The initial number of root nodes is n 31 sort (EG + 1, EG + m + 1, cmp ); // sort the edge by weight from small to large 32 ans = 0; 33 for (int I = 1; I <= m; I ++) // select the edge 34 {35 if (cnt = 1) break Based on the weight from small to large; // when the root node has only one, 36 int t1 = Find (EG [I]. u), t2 = Find (EG [I]. v); 37 if (t1! = T2) // select this edge if not in the same tree, 38 {39 ans + = EG [I]. w; 40 parent [t1] = t2; 41 cnt --; // reduce one root node by 42} 43} 44} 45 int main () 46 {47 while (scanf ("% d", & n), n) 48 {49 m = n * (n-1)/2; // complete figure 50 for (int I = 1; I <= m; I ++) 51 scanf ("% d", & EG [I]. u, & EG [I]. v, & EG [I]. w); 52 Kruskal (); 53 printf ("% d \ n", ans); 54} 55 return 0; 56}