Minimum spanning tree (Kruskal algorithm template)

Kruskal algorithm:

The Kruskal algorithm is another method to find the minimum spanning tree of the connected network. The idea of ​​this algorithm is to add edges from small to large. It is a greedy algorithm. The time of the algorithm is mainly spent on sorting the edges. The time complexity is O(eloge) , Suitable for finding the minimum spanning tree of graphs with fewer edges.

Algorithm steps:
1. Record the edge information, with the number of the point corresponding
to the edge 2. Sort by edge weight
3. Take an edge from small to large each time, if the two points are not the same set, merge; otherwise Just continue to look at the next edge
. 4. When the number of edges is n-1, the traversal ends, and the minimum spanning tree
is obtained. Algorithm steps:
1. Record the information of the edge, with the number of the point corresponding
to the edge 2. Sort by edge weight
3 Each time one edge is taken from small to large, if the two points are not the same set, merge; otherwise, continue to look at the next edge
4. When the number of edges is n-1, the traversal ends and the minimum spanning tree is obtained

Kruskal algorithm template:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const int N = 100010;

typedef struct{
    
    
    int u;
    int v;
    int w;
} Edge;

Edge E[N];  //存边
int S[N];   //并查集
int n, e, minSum;	//n是点数,e是无向边的边数 

//路径压缩
int find(int x){
    
    
	if(S[x] < 0) return x;
	return S[x] = find(S[x]);
} 

//按秩归并
void Union(int root1, int root2){
    
    
	if(S[root1] < S[root2])
		S[root2] = root1;
	else if(S[root1] == S[root2]){
    
    
		S[root1]--;
		S[root2] = root1;
		}
	else{
    
    
		S[root1] = root2;
		}
} 

//按边权从小到大排序 
int cmp(const void *a, const void *b){
    
    
	return ((Edge*)a)->w - ((Edge*)b)->w;
} 

void Kruskal(){
    
    
	memset(S, -1, sizeof(S));
	qsort(E, e, sizeof(Edge), cmp);
	int cnt = 0, idx = 0;
	while(cnt != n - 1){
    
    	//共需要添加n-1条边  
		int x1 = E[idx].u, x2 = E[idx].v;
		int root1 = find(x1);
		int root2 = find(x2);
		if(root1 != root2){
    
    
			Union(root1, root2);
			minSum += E[idx].w;
			cnt++;
			}
		idx++;
		}
}

int main(void){
    
    
    scanf("%d %d", &n, &e);
    int a, b, c;
    for(int i = 0; i < e; i++){
    
    
    	scanf("%d %d %d", &a, &b, &c);
    	E[i].u = a, E[i].v = b, E[i].w = c;
    	}
    Kruskal();
    printf("%d\n", minSum);
    return 0;
}

Guess you like

Origin blog.csdn.net/mingjiweixiao/article/details/113871123