Author: slyar Source: slyar home (www.slyar.com), please note, thank you for your cooperation.
Today, the data structure class talks about the Kruskal algorithm and prim algorithm of the Minimum Spanning Tree, but they are only concepts. They may be afraid that they will not understand it. We will not talk about Algorithm Implementation in any case.
In the afternoon, I ran to the library to read the Kruskal algorithm, and found that the introduction to algorithms is really a book of Niu XXXX. After reading it, I suddenly became very cheerful, we were surprised to find that the Kruskal algorithm was used for the previous two days of research and collection...
Kruskal is suitable for sparse graphs. It is a greedy algorithm. To minimize the weight of each edge in the Spanning Tree, the weight of each edge in the spanning tree should be as small as possible.
Specific practice: Find the edge with the minimum weight in all edges connected to any two sides in the forest. If you add it to the Spanning Tree, no loop is generated, it is an edge in the Spanning Tree. The key here is how to determine "add it to the spanning tree without generating a loop ".
An approach provided in introduction to algorithms is to use an "non-intersecting set data structure", that is, querying sets. The specific implementation depends on the Code. The core content is that if two nodes belong to the same tree (find_set), then they will be merged to form a loop.
Programming: For the next undirected graph, all edges and weights are given, and the Kruskal algorithm is used to find the Minimum Spanning Tree.
Input data:
11
A B 7
A d 5
B c 8
B d 9
B E 7
C e 5
D e 15
D F 6
E f 8
E G 9
F g 11
Output:
A-D: 5
C-E: 5
D-F: 6
A-B: 7
B-E: 7
E-G: 9
Total: 39
The Code is as follows. In fact, the code can be optimized in many ways. For example, when the number of edges of the generated tree is equal to n-1, the loop can be stopped... because it is not an ACM question, optimization is omitted and not written. It is only used for algorithm learning...
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
# Include <stdio. h> # include <stdlib. h> # define max 100/* defines the edge (x, y). The weight is w */typedef struct {int X, Y; int W;} edge; edge e [Max];/* Rank [x] indicates the rank of x */INT rank [Max]; /* father [x] indicates the parent node of x */INT father [Max]; int sum;/* comparison function, by weight (if the value is the same, X coordinates are used) non-descending order */int cmp (const void * a, const void * B) {If (* (edge *) ). W = (* (edge *) B ). w) {return (* (edge *) ). x-(* (edge *) B ). x;} return (* (edge *) ). w-(* (edge *) B ). w;}/* initialize the Set */void Make_set (int x) {FATHER [x] = x; rank [x] = 0;}/* searches for the set of X elements, compression path */INT find_set (int x) {If (X! = Father [x]) {FATHER [x] = find_set (father [x]);} return father [X];}/* merge X, set of y */void Union (int x, int y, int W) {If (x = y) return; /* connect a tree with a lower rank to a tree with a higher rank */If (rank [x]> rank [y]) {FATHER [y] = x ;} else {If (rank [x] = rank [y]) {rank [y] ++;} father [x] = y;} sum + = W ;} /* main function */INT main () {int I, n; int X, Y; char CHX, chy; /* Number of read edges */scanf ("% d", & N); getchar ();/* read edge information and initialize the Set */for (I = 0; I <n; I ++) {scanf ("% C % C % d ", & CHX, & chy, & E [I]. w); getchar (); e [I]. X = CHX-'A'; E [I]. y = chy-'A'; make_set (I);}/* sort edges */qsort (E, N, sizeof (edge), CMP); sum = 0; for (I = 0; I <n; I ++) {x = find_set (E [I]. x); y = find_set (E [I]. y); If (X! = Y) {printf ("% C-% C: % d/N", E [I]. X + 'A', E [I]. Y + 'A', E [I]. w); Union (X, Y, E [I]. w) ;}} printf ("Total: % d/N", sum); // system ("pause"); Return 0 ;} |