Kruskal算法:用来求解最小生成树的算法,同样使用贪心思想,只不过是边的权值最小来贪心。
Prim算法和Kruskal算法都是求解最小生成树的算法
只是Prim算法在执行时,是枚举图中所有结点,故比较适用稠密图(即结点少,边多),而Kruskal算法在执行时,是枚举所有边,故比较适用稀疏图(即结点多,边数少)。
Kruskal算法:
1、构造结构体,里面存放边的起始结点,终止结点,边的权值。
struct edge{
int start;//起始结点
int end;//终止结点
int weight;//边的权值
};
2、将边按照从小到大排序。
3、枚举所有边,若边的起始结点和终止结点不在一个集合中。则合并两个结点,然后把当前的边加入到最小生成树中,并更新最小生成树的总的边权。
4、重复上述过程,直到最小生成树的中有 n - 1 条边,n为结点数,退出循环。
5、检查最小生成树的边的条数是否为 n - 1,若不是,则表示该图为非连通图,返回-1,否则返回最小生成树总的边权。
样例:
输入:
6 10//6个顶点,10条边。以下10行为10条边
0 1 4//边0->1与1->0的边权为4,下同
0 4 1
0 5 2
1 2 1
1 5 3
2 3 6
2 5 5
3 4 5
3 5 4
4 5 3
输出:
11
解题思路;
使用并查集来表示两个结点是否在一个集合中,若不在,就合并(这是并查集的方法)
若并查集不是很清楚的,可以看 算法笔记—并查集 这部分。
下面为实现代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int max_v = 110;//点的最大值
const int max_e = 10010;//边的最大值
struct edge
{
int start;//起始结点
int end;//终止结点
int weight;//两结点之间的边
}E[max_e];//表示最多有max_e 条边
bool cmp(edge e1,edge e2){
return e1.weight < e2.weight;
}
int father[max_v];//并查集数组
/**
* @description: 查找当前结点的父结点
* @param : 要查找的结点
* @return: 返回x的根结点
*/
int find_father(int x){
int temp = x;//暂时存放需要查询的结点
while (x != father[x])
{
x = father[x];
}
//此时 temp 的根结点为 x
//下面为路径压缩
while (temp != father[temp])
{
int z = temp;
temp = father[temp];
father[z] = x;
}
return x;
}
/**
* @description: kruskal算法
* @param : n 表示结点数; m 表示边数
* @return: 返回最小生成树的边权之和
*/
int kruskal(int n,int m){
int result = 0;//最小生成树的边权之和
int edge_num = 0;//表示当前最小生成树的边数
//初始化father数组
for(int i = 0;i < n;i++){
father[i] = i;
}
sort(E,E + m,cmp);//将边的权值按照从小到大的顺序排列
//枚举所有的边
for(int i = 0;i < m;i++){
int start_father = find_father(E[i].start);
int end_father = find_father(E[i].end);
if(start_father != end_father){
father[start_father] = end_father;//合并集合
result += E[i].weight;
edge_num++;
if(edge_num == n - 1){
//边数等于结点数 - 1 即已经为最小生成树边的最大值
break;
}
}
}
if(edge_num != n - 1){
//表示给定的图不是连通图
return -1;
}
return result;
}
int main(){
int n,m;
cin >> n >> m;
for(int i = 0; i < m; i++){
cin>>E[i].start>>E[i].end>>E[i].weight;
}
int result = kruskal(n,m);
cout<<result<<endl;
system("pause");
return 0;
}
运行结果: