Kruskal思路:将所有边按从小到大排序,依次选边,若加入该边不构成回路,就将该边加入最小树中;
需要用到并查集。
#include <stdio.h>
#include <string.h>
#include <algorithm>
struct node{
int u, v, w;
};
const int SIZE = 1000;
node edge[SIZE];
int graph[SIZE][SIZE], check[SIZE], minW = 0;
bool compare(node a, node b){
return a.w<b.w;
}
void initi(int n){
for(int i = 1;i <= n;i++)
check[i] = i;
}
int GetFather(int x){
if (x != check[x])
check[x] = GetFather(check[x]);
return check[x];
}
void Union(int x, int y){
int fx =GetFather(x);
int fy = GetFather(y);
if(fx != fy)
check[fx] = fy;
}
void Kruskal(int n){
for(int i = 0;i < n;i++)
if(GetFather(check[edge[i].u]) != GetFather(check[edge[i].v])){
Union(edge[i].u,edge[i].v);
graph[edge[i].u][edge[i].v] = graph[edge[i].v][edge[i].u] = edge[i].w;
minW += edge[i].w;
}
}
int main(){
int n, m, i;
memset(graph, 0, sizeof(graph));
scanf("%d%d", &n, &m);
for(i = 0;i < n;i++)
scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
initi(m);
std::sort(edge, edge+n, compare);
Kruskal(n);
for(i = 0;i < n;i++){
for(int j = 0;j < n;j++)
printf("%d ", graph[i][j]);
printf("\n");
}
printf("%d", minW);
return 0;
}
/**
8 9
6 7 1
2 8 2
5 6 2
0 1 4
2 5 4
2 3 7
0 7 8
3 4 9
37
**/