算法——最小生成树

Prim算法:

算法步骤:
1.选择一个起始节点作为最小生成树的起点。
2.将该起始节点加入最小生成树集合,并将其标记为已访问。
3.在所有与最小生成树集合相邻的边中,选择权重最小的边和它连接的未访问节点。
4.将该边和节点加入最小生成树集合,并将该节点标记为已访问。
重复步骤3和步骤4,直到最小生成树集合包含了图中的所有节点。

#include<string>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;int n;
int wei[101][101];
bool visit[101];int prim()
{int res = 0;//总共加n-1条边for (int k = 0; k < n - 1; k++){int mi = 999999;int idex;//先把节点1加入,所以是从2开始遍历for (int i = 2; i <= n; i++){if (visit[i] == 1){continue;}//找到当前已经加入的集合到其余节点的最小边的距离if (mi > wei[1][i]){mi = wei[1][i];idex = i;}}visit[idex] = 1;res += wei[1][idex];for (int i = 2; i <= n; i++){//更新当前已经加入的集合到其余节点的最小边的距离,统一以1为标记点。//新加入的为index,所以对index往外的每条边都要判断是否需要更新if (wei[idex][i] < wei[1][i]){wei[1][i] = wei[idex][i];}}}return res;
}int main()
{cin >> n;for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){cin >> wei[i][j];}}cout << prim();
}
堆优化Prim算法:

算法步骤
初始化dist 数组为INF,表示所有节点到集合的距离为无穷大。
创建一个小根堆,堆中的元素为(dist 值, 节点编号)。
堆中先插入 ( 0 , 1 )  表示节点1进入集合, dist 值为 0。
每次从堆中取出 dist 值最小的元素 (d,u),将u加入集合。
对 u 相邻的所有节点 v,更新 dist[v]=min(dist[v],g[u][v]),并更新堆中的相应元素。
重复步骤 4、5,直到所有节点都加入集合。
最后根据取出的 dist 值之和求得最小生成树权重。

#define _CRT_SECURE_NO_WARNINGS#include<iostream>
#include<cstring>
#include<vector>
#include<queue>using namespace std;const int N = 510, M = 1e5 + 10;
typedef pair<int, int> PII;
bool st[N]; // 标记节点是否已经加入最小生成树
int n, m, dist[N]; // dist数组用于记录每个节点到最小生成树的距离
int h[N], e[M], ne[M], idx, w[M]; // 邻接表存储图的边信息void add(int a, int b, int c)
{e[idx] = b; // 存储边的另一个节点w[idx] = c; // 存储边的权值ne[idx] = h[a]; // 将边插入到节点a的邻接表头部h[a] = idx++; // 更新节点a的邻接表头指针
}int Prim()
{int res = 0, cnt = 0; // res用于记录最小生成树的权值和,cnt用于记录已经选择的边数priority_queue<PII, vector<PII>, greater<PII>> heap; // 最小堆,用于选择最短边memset(dist, 0x3f, sizeof dist); // 初始化dist数组为无穷大heap.push({ 0, 1 }); // 将节点1加入最小堆,距离为0dist[1] = 0; // 节点1到最小生成树的距离为0while (heap.size()){auto t = heap.top(); // 取出最小堆中距离最小的节点heap.pop();int ver = t.second, destination = t.first; // ver为节点,destination为距离if (st[ver]) continue; // 如果节点已经在最小生成树中,跳过st[ver] = true; // 将节点标记为已经加入最小生成树res += destination; // 更新最小生成树的权值和cnt++; // 增加已选择的边数// 遍历节点ver的所有邻接边for (int i = h[ver]; i != -1; i = ne[i]){auto u = e[i]; // 邻接边的另一个节点if (dist[u] > w[i]){dist[u] = w[i]; // 更新节点u到最小生成树的距离heap.push({ dist[u], u }); // 将节点u加入最小堆}}}// 如果最小生成树的边数小于n-1,则图不连通,返回0x3f3f3f3f表示不可达if (cnt < n) return 0x3f3f3f3f;return res; // 返回最小生成树的权值和
}int main()
{cin.tie(0);ios::sync_with_stdio(false);memset(h, -1, sizeof h); // 初始化邻接表头指针为-1cin >> n >> m; // 输入节点数和边数for (int i = 0; i < m; ++i){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c); // 添加无向图的边到邻接表中}int t = Prim(); // 计算最小生成树的权值和if (t == 0x3f3f3f3f)cout << "impossible" << endl; // 输出不可达elsecout << t << endl; // 输出最小生成树的权值和return 0;
}

Kruskal算法:

使用结构体存图,结构体中存放点,点,以及这两个点之间边的长度。

首先将结构体排序,按照边的大小从小到大排序。

然后按照边从小到大的顺序依次加入集合。若发现当前边已经在集合中了则跳过。

	// Kruskal 算法求最小生成树 #include <cstdio>#include <string>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 2e5 + 10; struct node {int x,y,z;}edge[maxn];bool cmp(node a,node b) {return a.z < b.z;}int fa[maxn];int n,m;int u,v,w; long long sum;int get(int x) {return x == fa[x] ? x : fa[x] = get(fa[x]);}int main(void) {scanf("%d%d",&n,&m);for(int i = 1; i <= m; i ++) {scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z);}for(int i = 0; i <= n; i ++) {fa[i] = i;}sort(edge + 1,edge + 1 + m,cmp);// 每次加入一条最短的边for(int i = 1; i <= m; i ++) {int x = get(edge[i].x);int y = get(edge[i].y);if(x == y) continue;fa[y] = x;sum += edge[i].z;}int ans = 0;for(int i = 1; i <= n; i ++) {if(i == fa[i]) ans ++;}if(ans > 1) puts("impossible");else printf("%lld\n",sum);return 0;} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/792293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【TC3xx芯片】TC3xx芯片RAM的错误检测

目录 前言 正文 1.有哪些RAM及其主要功能 2.谁来实现RAM监控

Redis数据库②高可用+持久化+性能管理

目录 一.高可用 二.持久化 1.Redis 提供两种方式进行持久化 2.RDB 持久化 &#xff08;1&#xff09;手动触发 &#xff08;2&#xff09;自动触发 &#xff08;3&#xff09;执行流程 &#xff08;4&#xff09;启动时加载 3.AOF持久化 &#xff08;1&#xff09;开…

【NC50937】货仓选址

题目 货仓选址 二分&#xff0c;前缀和&#xff0c;数学推导 思路 由题意可知货仓的位置是可以和商店的位置重合的。首先应该将商店的坐标从小到大排序&#xff0c;然后假设商店的坐标为 a i a_i ai​&#xff0c;货仓的坐标为 x x x&#xff0c;货仓左侧第一家商店&#x…

SpringBoot整合Flowable/Activiti

SpringBoot版本: 2.0.1.RELEASE Flowable版本: 6.3.1 Activiti版本: 6.0.0 一.添加pom依赖 因为之前我整合的时候有报错关于sqlsession的错误,后面查询文章才发现flowable要排除掉mybatis,又没说具体排除哪一个,所以我这干脆全部排除了 <!-- Flowable dependencies -->…

练气第六天

问:ANR怎么分析&#xff1f; ANR问题&#xff0c;这其实是一个非常综合性的问题&#xff0c;因为anr会涉及CPU负载&#xff0c;内存空间大小&#xff0c;线程锁&#xff0c;GC回收&#xff0c;这里面每个点&#xff0c;都是非常考验我们基本功的。 分析ANR问题&#xff0c;需…

【Java SE】继承

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 继承1.1 继承是什么1.2 继承的意义1.3 继承的语法1.4 继承的方式1.5 子类中访问父类成员1.5.1 子类中访问…

js类型转换

类型转换只有这四种&#xff0c;例如如果要对象转数字&#xff0c;那么就需要先把对象转成原始类型&#xff0c;再从原始类型转到数字。 空数组转原始类型是一个空字符串。空对象转原始类型是[object Object]。 let a {} console.log(a);// NaN //等价于 a->原始 然后原始…

北京大学创新推出ManipLLM黑科技 | 大幅提升机器人操作的鲁棒性与智能性

机器人操作依赖于准确预测接触点和执行器方向以确保成功操作。然而&#xff0c;基于学习的机器人操作&#xff0c;在模拟器中仅针对有限类别进行训练&#xff0c;往往难以实现泛化&#xff0c;特别是在面临大量类别时。 因此&#xff0c;作者提出了一种创新的方法&#xff0c;…

使用c++ lambda表达式的注意事项

回答来自【通义灵码】 使用C中的lambda表达式时&#xff0c;应当注意以下几点&#xff1a; 语法结构: 捕获列表 ([captures])&#xff1a;位于lambda表达式起始处&#xff0c;定义了lambda可以访问的外部作用域中的变量。可选择捕获方式包括&#xff1a; 按值捕获 ([])&#x…

网络安全基础之网络协议与安全威胁

OSI(OpenSystem Interconnect)&#xff0c;即开放式系统互联。 一般都叫OSI参考模型&#xff0c;是ISO(国际标准化组织)组织在1985年研究的网络互联模型。 网络协议的简介&#xff1a; 定义&#xff1a;协议是网络中计算机或设备之间进行通信的一系列规则集合。 什么是规则?…

Android操作sqlite数据库

Sqlite数一种轻量级的关系型数据库&#xff0c;android里面可以用来持久化存储一些用户数据。 一、SQLiteOpenHelper方式 SQLiteOpenHelper是原生的数据库帮助类&#xff0c;继承这个类&#xff0c;用来创建&#xff0c;更新数据库的操作 public class MySqliteOpenHelper e…

算法整理:链表

链表定义 struct ListNode { int val;ListNode *next;ListNode(int x) : val(x), next(nullptr) {} }; 链表的遍历&#xff1a;ListNode phead; while(p!null) pp.next; 找到链表的尾结点&#xff1a;phead; while(p.next!null)pp.next; 链表节点的个数&#xff1a; phead…

LocalDateTime 前后端传输问题

后端使用json形式接收前端传来的LocalDateTime&#xff0c;则添加下面的JsonFormat注释 同时后端返回给前端的json中带有LocalDateTime的话&#xff0c;也添加JsonFormat注解 JsonFormat(pattern "yyyy-MM-dd HH:mm:ss", timezone "GMT8") private Loca…

蓝桥杯真题:七段码

import java.util.Scanner; import java.util.ArrayList; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args){// 连接关系图int[][] map new int[][]{{0, 1, 0, 0, 0, 1, 0},{1, 0, 1, 0, 0, 0, 1},{0, 1, 0, 1, 0, 0…

通讯录项目实现

引言&#xff1a;通过顺序表的逻辑实现通讯录。这里就不讲关于顺序表的函数了。如果有不明白的可以看我写的顺序表的博客。 目录 顺序表与通讯录的比较 各源文件文件大榄 Contact.c中通讯录相关函数的定义 初始化和销毁通讯录 添加联系人&#xff1a; 删除联系人&#xf…

c++的学习之路:10、string(2)

本章主要说一下模拟实现string类的部分功能&#xff0c;文章末附上所有代码。 目录 一、构造函数与析构函数 二、拷贝构造 三、c_str 四、【】和迭代器的遍历与访问 五、size 六、判断 七、reserve 八、push_back 九、resize 十、append 十一、 十二、insert 十…

Spirngboot JWT快速配置和使用

2、JWT 2.1、JWT介绍 JWT是JSON Web Token的缩写&#xff0c;即JSON Web令牌&#xff0c;是一种自包含令牌。 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。 JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息&#xff0c;以便于从…

day25打卡:回溯算法part02

day25打卡&#xff1a;回溯算法part02 216.组合总和三 原题链接 代码随想录链接 和经典的回溯题目很相似&#xff0c;只是需要在每层for循环中都记录当前的总和&#xff1b; Java代码如下&#xff1a; class Solution {List<List<Integer>> result new Arra…

【DevOps工具篇】Keycloak中设置与OpenLDAP认证集成

【DevOps工具篇】Keycloak中设置与OpenLDAP认证集成 目录 【DevOps工具篇】Keycloak中设置与OpenLDAP认证集成步骤 1. 启动一个用于安装 OpenLDAP 的 EC2 实例步骤 2. 安装 OpenLDAP启动 docker 容器查看所有用户信息extended LDIFLDAPv3base <ou=users,dc=example,dc=org&g…

Redis的5大常见数据类型的用法

上一篇文章我们讲了Redis的10大应用场景&#xff0c;这一篇文章就针对Redis的常用数据结构进行一个说明&#xff0c;通过示例的形式演示每一种数据结构如何使用。 当涉及Redis的数据操作时&#xff0c;不同数据类型对应的不同数据结构&#xff0c;如下就对5大常用的数据类型进行…