Kruskal 알고리즘 :
Kruskal 알고리즘은 연결된 네트워크의 최소 스패닝 트리를 찾는 또 다른 방법입니다.이 알고리즘의 아이디어는 작은 것에서 큰 것까지 가장자리를 추가하는 것입니다. 탐욕스러운 알고리즘입니다. 알고리즘의 시간은 주로 네트워크를 정렬하는 데 사용됩니다. 시간 복잡도는 O (eloge)이며, 간선 수가 적은 그래프의 최소 스패닝 트리를 찾는 데 적합합니다.
알고리즘 단계 :
1. 에지에 해당하는 포인트의 번호와 함께 에지 정보를 기록합니다
. 2. 에지 가중치별로 정렬
3. 두 포인트가 동일한 세트가 아닌 경우 매번 작은 에지에서 큰 에지로 에지를 가져 와서 병합합니다. 그렇지 않으면 계속해서 다음 에지를
봅니다 4. 에지 수가 n-1이면 순회가 종료되고 최소 스패닝 트리
가 획득됩니다 알고리즘 단계 :
1. 에지의 정보를 번호와 함께 기록합니다.
가장자리에 해당하는 점 2. 가장자리 가중치로 정렬
3 작은 가장자리에서 큰 가장자리로 이동할 때마다 두 지점이 동일하지 않으면 병합하고 그렇지 않으면 다음 가장자리를 계속 봅니다
. 4. 숫자가 가장자리 수는 n-1, 순회 끝 및 최소 스패닝 트리
Kruskal 알고리즘 템플릿 :
#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;
}