#include<stdio.h>
#include<stdlib.h>
typedef struct
{
}edger;
edger edge[900];
int father[900],dian,bian,cost;
*father数组记录集合的代表人物,每次代表人物选取该集合中的最小数字作为代表,这是并查集的典型运用*
void paixu()
{
}
*将各个边的权值进行冒泡排序,从而方便进行后面的贪心策略*
void setfather(int i)
{
}
*对不在一个集合内的两点进行处理(也就是说这条边还没有加入到这棵最小生成树里面去),对他们的代表人物进行重新整合建立,先找出它们各自的代表人物,然后比较两个代表人物的大小,小的数从而成为新的代表人物(也就是说大一点的代表人物的代表人物从自己变成了更小的另一个)*
int findfather(int k)
{
}
*找到这个数的祖宗的祖宗的祖宗……就这样一直找下去,直到找到一个祖宗是自己的数为止,那么这个数显然是这一个集合的代表人物*
int main()
{
*初始化祖宗,各自的祖宗最开始都是自己,也就是说自己是一个集合*
*对边的数据结构进行扫描,这包括边的首末两点以及这条边的权值*
*排序,贪心策略的前提*
*贪心策略的初始进行,首先采纳最小的那么一棵"树叶"从而而变成了树的"根",后面的再依次贪心加入*
*则每采取贪心策略赚取一片树叶,那么这条边与之相关联的两点的祖宗就要重新设置一下,setfather,那么到最后一共有n-1条边*
printf("%d",cost);
}
测试数据:
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) (6,5) (5,4) (4,3) (3,2) (2,7)
最小代价:99
个人觉得kruskal算法理解起来其实更为容易,但是在编译程序过程中还是有些小细节要注意的,特别是并查集的运用。