克鲁斯卡尔算法
求加权连通图的最小生成树的算法。
贪心求最小生成树:上代码:
(C++)
//#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<math.h>
#include<stack>
using namespace std ;
typedef long long ll;
#define MAXN 10005
#define INF 0x3f3f3f3f
#define MALL (BiTnode *)malloc(sizeof(BiTnode));
int ves[MAXN]; //标识各个顶点所属的连通分量。
struct stu //从u到v有一条权值为len的边
{
int u, v, lowcoat;
}edge[MAXN];
void init(int n) //输入m条边之间的关系
{
for(int i=0; i<n; ++i)
{
int u, v, len;
cin >> u >> v >> len;
edge[i].u = u;
edge[i].v = v;
edge[i].lowcoat = len;
}
}
int cmp(stu x, stu y) //按边的大小降序排列
{
return x.lowcoat < y.lowcoat;
}
void Kruskal(int n, int m) //克鲁斯卡尔算法
{
sort(edge, edge+m, cmp); //先降序,共有m条边关系,固对该m条边排序
for(int i=0; i<n; ++i) //初始化,每个顶点都为一个连通分量(自己是自己的连通分量)
ves[i] = i;
for(int i=0; i<m; ++i)
{
int u1 = edge[i].u; //取最小边
int v1 = edge[i].v;
int u2 = ves[u1]; //取边的始点和终点的连通分量
int v2 = ves[v1];
if(u2 != v2) //判断是否属于同一连通分量
{
cout << u1 << "--->" << v1 << '\n';
for(int j=0; j<m; ++j) //是,输出,并且加到同一连通分量上
{
if(ves[j] == v2)
ves[j] = u2;
}
}
}
}
int main()
{
cout << "请输入顶点的个数和边的关系数" << '\n';
int n, m; //n个顶点和m条边关系
cin >> n >> m;
cout << "\n请依次输入各组边的关系" << '\n';
init(m);
cout << "\n-----Kruskal生成最小生成树的途径是------" << '\n';
Kruskal(n, m);
}
可参考博客:普里姆算法
样例测试:
6 10
0 1 6
0 3 5
0 2 1
1 2 5
2 3 5
1 4 3
2 4 6
2 5 4
3 5 2
4 5 6
样例输出: