标签:
http://www.51nod.com/
Kruskal算法的高效实现需要一种称作并查集的结构。我们在这里不介绍并查集,只介绍Kruskal算法的基本思想和证明,实现留在以后讨论。






第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000) 第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
输出最小生成树的所有边的权值之和。
9 14 1 2 4 2 3 8 3 4 7 4 5 9 5 6 10 6 7 2 7 8 1 8 9 7 2 8 11 3 9 2 7 9 6 3 6 4 4 6 14 1 8 8
37
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int parent[10];
int n,m;
int i,j;
struct edge{
int u,v,w; //边的顶点,权值
}edges[10];
//初始化并查集
void UFset(){
for(i=1; i<=n; i++) parent[i] = -1;
}
//查找i的跟
int find(int i){
int temp;
//查找位置
for(temp = i; parent[temp] >= 0; temp = parent[temp]);
//压缩路径
while(temp != i){
int t = parent[i];
parent[i] = temp;
i = t;
}
return temp;
}
//合并两个元素a,b
void merge(int a,int b){
int r1 = find(a);
int r2 = find(b);
int tmp = parent[r1] + parent[r2]; //两个集合节点数的和
if(parent[r1] > parent[r2]){
parent[r1] = r2;
parent[r2] = tmp;
}else{
parent[r2] = r1;
parent[r1] = tmp;
}
}
void kruskal(){
int sumWeight = 0;
int num = 0;
int u,v;
UFset();
for(int i=0; i<m; i++)
{
u = edges[i].u;
v = edges[i].v;
if(find(u) != find(v)){ //u和v不在一个集合
printf("加入边:%d %d,权值: %d\n", u,v,edges[i].w);
sumWeight += edges[i].w;
num ++;
merge(u, v); //把这两个边加入一个集合。
}
}
printf("weight of MST is %d \n", sumWeight);
}
//比较函数,用户排序
int cmp(const void * a, const void * b){
edge * e1 = (edge *)a;
edge * e2 = (edge *)b;
return e1->w - e2->w;
}
int main() {
scanf("%d %d", &n, &m);
for(i=0; i<m; i++){
scanf("%d %d %d", &edges[i].u, &edges[i].v, &edges[i].w);
}
qsort(edges, m, sizeof(edge), cmp);
kruskal();
return 0;
}
/*
测试数据:
7 9
1 2 28
1 6 10
2 3 16
2 7 14
3 4 12
4 5 22
4 7 18
5 6 25
5 7 24
输出:
加入边:1 6,权值: 10
加入边:3 4,权值: 12
加入边:2 7,权值: 14
加入边:2 3,权值: 16
加入边:4 5,权值: 22
加入边:5 6,权值: 25
weight of MST is 99 */标签:
原文地址:http://blog.csdn.net/liangzhaoyang1/article/details/51169090