当前位置: 首页 > news >正文

kruskal求最小生成树

算法思路:

将所有边按照权值的大小进行升序排序,然后从小到大一一判断。

如果这个边与之前选择的所有边不会组成回路,就选择这条边分;反之,舍去。

直到具有 n 个顶点的连通网筛选出来 n-1 条边为止。

筛选出来的边和所有的顶点构成此连通网的最小生成树。

判断是否会产生回路的方法为:使用并查集。

在初始状态下给各个个顶点在不同的集合中。

遍历过程的每条边,判断这两个顶点的是否在一个集合中。

如果边上的这两个顶点在一个集合中,说明两个顶点已经连通,这条边不要。如果不在一个集合中,则要这条边。

 

//kruskal求最小生成树
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 2e5 + 9;struct Edge
{int a, b, w;bool operator< (const Edge& W) const{return w < W.w;}
} edges[N];int n, m, p[N], res, cnt;int find(int x)
{if (p[x] != x) p[x] = find(p[x]);return p[x];
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> n >> m;for (int i = 0; i < m; ++i){int a, b, w; cin >> a >> b >> w;edges[i] = { a, b, w };}//从小到大排序sort(edges, edges + m);//并查集数组初始化for (int i = 1; i <= n; ++i) p[i] = i;//如果这个边与之前选择的所有边不会组成回路,就选择这条边分;反之,舍去。//判断是否会产生回路的方法为:使用并查集。//每次将未加入的边加入到集合中去for (int i = 0; i < m; ++i){int a = edges[i].a, b = edges[i].b, w = edges[i].w;//不在一个集合里面a = find(a), b = find(b);if (a != b){res += w;cnt++;p[a] = b;//加入集合}}//如果集合中的边数小于n - 1,说明不存在最小生成树if (cnt < n - 1) cout << "impossible";else cout << res;return 0;
}

关于并查集可以看一下我写的这个篇文章: http://t.csdnimg.cn/ClmtA

 

 

http://www.lryc.cn/news/216121.html

相关文章:

  • 876. 链表的中间结点
  • 【机器学习】二、决策树
  • 低代码PAAS加速推进企业数字化转型
  • 时间复杂度为 O(nlogn) 的排序算法
  • 掌控你的Mac性能:System Dashboard Pro,一款专业的系统监视器
  • C++ Qt如何往Windows AppData目录写数据
  • xargs命令
  • 【原创】java+swing+mysql无偿献血管理系统设计与实现
  • C语言 Number 1 基本数据类型
  • mac录屏快捷键指南,轻松录制屏幕内容!
  • 精准测试是个错误
  • 算法通关村第四关|黄金挑战|表达式问题
  • Mac安装DBeaver
  • C++ 类 根据成员变量的指针获取类对象的指针
  • 图论08-图的建模-状态的表达与理解 - 倒水问题为例
  • sqlserver字符串拼接
  • MySQL-----事务
  • hive的安装配置笔记
  • lamba stream处理集合
  • 操作系统 day04(系统调用)
  • 【深度学习】pytorch——线性回归
  • golang工程——中间件redis,单节点集群部署
  • Lua基础
  • 微信小程序之开发工具介绍
  • 【AUTOSAR】【以太网】DoIp
  • 游戏中UI的性能优化手段
  • Idea快速生成测试类
  • Java文件操作详解
  • 二叉树系列主题Code
  • Leetcode 673. 最长递增子序列的个数 C++