kruskal(克鲁斯卡尔)算法
kruskal是一种基于并查集和贪心思想的最小生成树算法
算法思路:将图存入结构体数组中并按照边的权值排序,每次都选择权值最小且边两边的点不在同一集合中,将这条边加入到树中,然后合并两个集合。重复上述操作直到选择的边的个数是n-1时停止。
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e5 + 5, INF = 0x3f3f3f3f;
//int G[N][N];
struct book
{
int u, v, w;
}e[N];
//bool vis[N];//判断点是否使用
//int tu[N][N];//将图存入邻接矩阵
//int ju[N];//点到集合的最短距离
int ans = 0, cnt = 0, n;
int ji[N];//并查集
//int zhi[N];//秩数组记录每一个节点的深度
bool cmp(book a, book b)
{
return a.w < b.w;
}
int find(int x)//查找
{
if (ji[x] == x)
{
return x;
}
else
{
return find(ji[x]);
}
}
bool kruskal(int m)
{
for (int i = 0; i < m; ++i)
{
int x = find(e[i].u);
int y = find(e[i].v);
if (x != y)
{
ji[y] = x;
ans += e[i].w;
cnt++;
}
}
return cnt == n - 1;
}
int main()
{
int m;
cin >> n >> m;
for (int i = 0; i < n; ++i)//初始化
{
ji[i] = i;
}
for (int i = 0; i < m; ++i)
{
cin >> e[i].u >> e[i].v >> e[i].w;
}
sort(e, e + m, cmp);
bool s = kruskal(m);
if (s)
{
cout << ans << endl;
}
return 0;
}