NO.92十六届蓝桥杯备战|图论基础-最小生成树-Prim算法-Kruskal算法|买礼物|繁忙的都市|滑雪(C++)
一个具有n个顶点的连通图,其⽣成树为包含n-1条边和所有顶点的极⼩连通⼦图。对于⽣成树来说,若砍去⼀条边就会使图不连通图;若增加⼀条边就会形成回路。
![![[Pasted image 20250414153851.png]]](https://i-blog.csdnimg.cn/direct/3ef926efda0d447a945ae98b716bfcb7.png)
![![[Pasted image 20250414153858.png]]](https://i-blog.csdnimg.cn/direct/36c37ec1209f4e7f97f78be2dbd43cdc.png)
⼀个图的⽣成树可能有多个,将所有⽣成树中权值之和最⼩的树称为最⼩⽣成树。
构造最⼩⽣成树有多种算法,典型的有普利姆(Prim)算法和克鲁斯卡尔(Kruskal)算法两种,它们都是基于贪⼼的策略。
Prim算法
核⼼:不断加点。
Prim 算法构造最⼩⽣成树的基本思想:
- 从任意⼀个点开始构造最⼩⽣成树;
- 将距离该树权值最⼩且不在树中的顶点,加⼊到⽣成树中。然后更新与该点相连的点到⽣成树的最短距离;
- 重复2操作n次,直到所有顶点都加⼊为⽌
![![[Pasted image 20250414164712.png]]](https://i-blog.csdnimg.cn/direct/c331cc701a3840038d22bf180da89e78.png)
11 - 51 - 5 - 21 - 5 - 2
1 - 41 - 5 - 2 - 3
1 - 4
P3366 【模板】最小生成树 - 洛谷
代码实现-邻接矩阵:
#include <bits/stdc++.h>
using namespace std;const int N = 5010, INF = 0x3f3f3f3f;int n, m;
int edges[N][N]; //邻接矩阵int dist[N]; //某个点距离生成树的最短距离
bool st[N]; //标记哪些点已经加入到生成树int prim()
{//初始化memset(dist, 0x3f, sizeof dist);dist[1] = 0;int ret = 0;for (int i = 1; i <= n; i++) //循环加入n个点{//1.找最近点int t = 0;for (int j = 1; j <= n; j++)if (!st[j] && dist[j] < dist[t])t = j;//判断是否连通if (dist[t] == INF) return INF;st[t] = true;ret += dist[t];//2.更新距离for (int j = 1; j <= n; j++) //枚举t能走到哪{dist[j] = min(dist[j], edges[t][j]);}}return ret;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;//初始化为无穷memset(edges, 0x3f, sizeof edges);for (int i = 1; i <= m; i++){int x, y, z; cin >> x >> y >> z;//有重边求最小值edges[x][y] = edges[y][x] = min(edges[x][y], z);}int ret = prim();if (ret == INF) cout << "orz" << endl;else cout << ret << endl;return 0;
}
代码实现-邻接表-vector数组:
#include <bits/stdc++.h>
using namespace std;typedef pair<int, int> PII;const int N = 5010, INF = 0x3f3f3f3f;int n, m;
vector<PII> edges[N];int dist[N];
bool st[N];int prim()
{memset (dist, 0x3f, sizeof dist);dist[1] = 0;int ret = 0;for (int i = 1; i <= n; i++){//1.找最近点int t = 0;for (int j = 1; j <= n; j++)if (!st[j] && dist[j] < dist[t])t = j;//判断是否连通if (dist[t] == INF) return INF;st[t] = true;ret += dist[t];//2.更新距离for (auto& p : edges[t]){int a = p.first, b = p.second;//t->a,权值是bdist[a] = min(dist[a], b);}}return ret;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= m; i++){int x, y, z; cin >> x >> y >> z;edges[x].push_back({y,z});edges[y].push_back({x,z});}int ret = prim();if (ret == INF) cout << "orz" << endl;else cout << ret << endl;return 0;
}
Kruskal算法
核⼼:不断加边。
Kruskal 算法构造最⼩⽣成树的基本思想:
- 所有边按照权值排序;
- 每次选出权值最⼩且两端顶点不连通的⼀条边,直到所有顶点都联通
![![[Pasted image 20250414201240.png]]](https://i-blog.csdnimg.cn/direct/24425e8f8b0a48c592964c6905b65218.png)
1 - 51 - 5 - 21 - 5 - 2
1 - 41 - 5 - 2 - 3
1 - 4
#include <bits/stdc++.h>
using namespace std;const int N = 5010, M = 2e5 + 10, INF = 0x3f3f3f3f;int n, m;
struct node
{int x, y, z;
}a[M];int fa[N]; //并查集bool cmp(node& a, node& b)
{return a.z < b.z;
}int find(int x)
{return x == fa[x] ? fa[x] : fa[x] = find(fa[x]);
}int kk()
{sort (a+1, a+1+m, cmp);int cnt = 0;int ret = 0;for (int i = 1; i <= m; i++){int x = a[i].x, y = a[i].y, z = a[i].z;int fx = find(x), fy = find(y);if (fx != fy){cnt++;ret += z;fa[fx] = fy;}}return cnt == n-1 ? ret : INF;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= m; i++) cin >> a[i].x >> a[i].y >> a[i].z;//初始化并查集for (int i = 1; i <= n; i++) fa[i] = i;int ret = kk();if (ret == INF) cout << "orz" << endl;else cout << ret << endl;return 0;
}
P1194 买礼物 - 洛谷
题⽬转化:
- 如果把每⼀个零⻝看成⼀个节点,优惠看成⼀条边,就变成在图中找最⼩⽣成树的问题。
- 因此,跑⼀遍kk算法即可。
注意:
- 存边的时候,没有必要存重复的,并且权值过⼤的也不需要存;
- 最终提取结果的时候,虽然有可能构造不出来⼀棵最⼩⽣成树,但是要在已有的构造情况下处理结果
#include <bits/stdc++.h>
using namespace std;const int N = 500 * 500 + 10;int a, n;int pos;
struct node
{int x, y, z;
}e[N];int fa[N];int find (int x)
{return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}int cnt, ret;bool cmp(node& a, node& b)
{return a.z < b.z;
}void kk()
{sort(e+1, e+1+pos, cmp);for (int i = 1; i <= pos; i++){int x = e[i].x, y = e[i].y, z = e[i].z;int fx = find(x), fy = find(y);if (fx != fy){cnt++;ret += z;fa[fx] = fy;}}
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> a >> n;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++){int k; cin >> k;if (i >= j || k > a || k == 0) continue;pos++;e[pos].x = i; e[pos].y = j; e[pos].z = k;}for (int i = 1; i <= n; i++) fa[i] = i;kk();cout << ret + (n - cnt) * a << endl;return 0;
}
P2330 [SCOI2005] 繁忙的都市 - 洛谷
定理:最⼩⽣成树就是瓶颈⽣成树。
在kk算法中,维护边权的最⼤值即可
#include <bits/stdc++.h>
using namespace std;const int N = 310, M = 8010;int n, m;
struct node
{int x, y, z;
}e[M];int fa[N];int find (int x)
{return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}int ret; //最大边的权值bool cmp(node& x, node& y)
{return x.z < y.z;
}void kk()
{for (int i = 1; i <= n; i++) fa[i] = i;sort(e+1, e+1+m, cmp);for (int i = 1; i <= m; i++){int x = e[i].x, y = e[i].y, z = e[i].z;int fx = find(x), fy = find(y);if (fx != fy){ret = max(ret, z);fa[fx] = fy;}}
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= m; i++) cin >> e[i].x >> e[i].y >> e[i].z;cout << n - 1 << " ";kk();cout << ret << endl;return 0;
}
P2573 [SCOI2012] 滑雪 - 洛谷
第⼀问:从起点开始,做⼀次dfs/bfs就可以扫描到所有的点。
第⼆问:因为有回溯的效果,相当于就是选择⼀些边,把所有的点都连接起来。但是需要注意:
- 由于这些边是有⽅向的,我们只要保证能从1位置出发,访问到所有的点即可。与最⼩⽣成树还是有差异的。
- 为了能保证选出来的边能够从1访问所有点,应该优先考虑去往更⾼位置的边,这样才能向下⾛到更低的位置
#include <bits/stdc++.h>
using namespace std;typedef long long LL;
typedef pair<int, int> PII;const int N = 1e5 + 10, M = 2e6 + 10;int n, m;
int h[N];vector<PII> edges[N];int fa[N];int find(int x)
{return fa[x] == x ? x : fa[x] = find(fa[x]);
}LL cnt, ret;
bool st[N];int pos;
struct node
{int x, y, z;
}e[M];void dfs(int u)
{cnt++;st[u] = true;for (auto& p : edges[u]){int v = p.first, k = p.second;pos++;e[pos].x = u; e[pos].y = v; e[pos].z = k;if (!st[v]) dfs(v);}
}bool cmp(node& a, node& b)
{int y1 = a.y, z1 = a.z, y2 = b.y, z2 = b.z;if (h[y1] != h[y2]) return h[y1] > h[y2];else return z1 < z2;
}void kk()
{for (int i = 1; i <= n; i++) fa[i] = i;sort (e+1, e+1+pos, cmp);for (int i = 1; i <= pos; i++){int x = e[i].x, y = e[i].y, z = e[i].z;int fx = find(x), fy = find(y);if (fx != fy){ret += z;fa[fx] = fy;}}
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= n; i++) cin >> h[i];for (int i = 1; i <= m; i++){int x, y, z; cin >> x >> y >> z; if (h[x] >= h[y]) edges[x].push_back({y, z});if (h[x] <= h[y]) edges[y].push_back({x, z});}dfs(1);cout << cnt << " ";kk();cout << ret << endl;return 0;
}
相关文章:
NO.92十六届蓝桥杯备战|图论基础-最小生成树-Prim算法-Kruskal算法|买礼物|繁忙的都市|滑雪(C++)
一个具有n个顶点的连通图,其⽣成树为包含n-1条边和所有顶点的极⼩连通⼦图。对于⽣成树来说,若砍去⼀条边就会使图不连通图;若增加⼀条边就会形成回路。 ⼀个图的⽣成树可能有多个,将所有⽣成树中权值之和最⼩的树称为最⼩⽣成树…...
第十四节:实战场景-何实现全局状态管理?
React.createElement调用示例 Babel插件对JSX的转换逻辑 React 全局状态管理实战与 JSX 转换原理深度解析 一、React 全局状态管理实现方案 1. Context API useReducer 方案(轻量级首选) // 创建全局 Context 对象 const GlobalContext createConte…...
数据驱动、精准协同:高端装备制造业三位一体生产管控体系构建
开篇引入 鉴于集团全面推行生产运营体建设以及对二级单位生产过程管控力度逐步加强,某高端装备制造企业生产部长王总正在开展新的一年企业生产管控规划工作,为了能够更好地进行体系规划与建设应用,特邀请智能制造专家小智来进行讨论交流。 王…...
航电系统之通信技术篇
航电系统(航空电子系统)的通信技术是现代航空器的核心技术之一,其核心目标是实现飞行器内部各系统之间以及飞行器与外部设备(如地面控制中心、其他飞行器等)之间高效、可靠的信息交互。随着航空技术的不断发展…...
Linux 日常运维命令大全
Linux 作为一种开源操作系统,在服务器运维中扮演着重要角色。掌握常用的 Linux 命令对于运维人员而言至关重要。本文将整理一份 Linux 服务器运维常用命令大全,帮助你在日常工作中提高效率和准确性。 1. 基础命令 基础命令是Linux操作的起点࿰…...
HTTP 3.0 协议的特点
HTTP/3 是互联网传输协议的一次重要升级,相较于 HTTP/2,它引入了多项显著改进和新特性。 基于 QUIC 协议: HTTP/3 采用了 QUIC(Quick UDP Internet Connections)作为底层传输协议,QUIC 基于 UDP࿰…...
[工具]Java xml 转 Json
[工具]Java xml 转 Json 依赖 <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --> <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.37</version> </dependen…...
「仓颉编程语言」Demo
仓颉编程语言」Demo python 1)# 仓颉语言写字楼管理系统示例(虚构语法)# 语法规则:中文关键词 类Python逻辑定义 写字楼管理系统属性:租户库 列表.新建()报修队列 列表.新建()费用单价 5 # 元/平方米方法 添加租户(名称, 楼层, 面积):…...
发现“横”字手写有难度,对比两个“横”字
我发现手写体“横”字“好看”程度,难以比得上印刷体: 两个从方正简体启体来的“横”字: 哪个更好看?我是倾向于左边一点。 <div style"transform: rotate(180deg); display: inline-block;"> 左边是我从方正简…...
深度学习3.1 线性回归
3.1.1 线性回归的基本概念 损失函数 梯度下降 3.1.2 向量化加速 %matplotlib inline import math import time import numpy as np import torch from d2l import torch as d2ln 1000000 #本机为了差距明显,选择数据较大,运行时间较长,可选…...
番外篇 | SEAM-YOLO:引入SEAM系列注意力机制,提升遮挡小目标的检测性能
前言:Hello大家好,我是小哥谈。SEAM(Squeeze-and-Excitation Attention Module)系列注意力机制是一种高效的特征增强方法,特别适合处理遮挡和小目标检测问题。该机制通过建模通道间关系来自适应地重新校准通道特征响应。在遮挡小目标检测中的应用优势包括:1)通道注意力增强…...
SpringBoot ApplicationEvent:事件发布与监听机制
文章目录 引言一、事件机制的基本概念二、创建自定义事件2.1 定义事件类2.2 发布事件2.3 简化的事件发布 三、创建事件监听器3.1 使用EventListener注解3.2 实现ApplicationListener接口3.3 监听非ApplicationEvent类型的事件 四、事件监听的高级特性4.1 条件事件监听4.2 异步事…...
[250415] OpenAI 推出 GPT-4.1 系列,支持 1M token
目录 OpenAI 推出 GPT-4.1 系列 OpenAI 推出 GPT-4.1 系列 OpenAI 宣布,新一代 GPT-4.1 模型系列正式发布,包括 GPT-4.1, GPT-4.1 mini 和 GPT-4.1 nano 三款模型,该系列模型在各项性能指标上全面超越 GPT-4o 和 GPT-4o mini,尤其…...
广东2024信息安全管理与评估一阶段答案截图
2023-2024 学年广东省职业院校技能大赛 高等职业教育组 信息安全管理与评估 赛题一 模块一 网络平台搭建与设备安全防护 一、 比赛时间 本阶段比赛时间为 180 分钟。 二、 赛项信息 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一…...
C++_设计模式\_观察者模式(Observer Pattern)
👋 Hi, I’m liubo👀 I’m interested in harmony🌱 I’m currently learning harmony💞️ I’m looking to collaborate on …📫 How to reach me …📇 sssssdsdsdsdsdsdasd🎃 dsdsdsdsdsddfsg…...
安卓手机如何改ip地址教程
对于安卓手机用户而言,ip修改用在电商、跨境电商、游戏搬砖、社交软件这些需要开多个账号的项目。因为多个设备或账号又不能在同一ip网络下,所以修改手机的IP地址防检测成为一个必要的操作。以下是在安卓手机上更改IP地址的多种方法及详细步骤࿰…...
从Shell到域控:内网渗透中定位域控制器的8种核心方法
在内网渗透中,定位域控制器(Domain Controller, DC)是攻防对抗的关键环节。本文结合实战经验与工具技术,总结出8种从Shell快速发现域控主机的方法,涵盖命令探测、网络扫描、日志分析等维度,助你系统…...
PHP腾讯云人脸核身获取Access Token
参考腾讯云官方文档: 人脸核身 获取 Access Token_腾讯云 public function getAccessToken(){$data [appId > , //WBappid,https://cloud.tencent.com/document/product/1007/49634secret > ,grant_type > client_credential, //授权类型version > 1…...
Kotlin 集合过滤全指南:all、any、filter 及高级用法
在 Kotlin 中,集合过滤是数据处理的核心操作之一。无论是简单的条件筛选,还是复杂的多条件组合,Kotlin 都提供了丰富的 API。本文将详细介绍 filter、all、any、none 等操作符的用法,并展示如何在实际开发中灵活运用它们。 1. 基础…...
解决6栈6层码头集装箱堆栈翻箱最优解问题
‘’’ con 1 origin_stack = [ [4, 4, 1, 0, 0, 0], # 第一栈 [4, 3, 2, 1, 0, 0], # 第二栈 [4, 2, 2, 1, 0, 0], # 第三栈 [3, 3, 3, 1, 0, 0], # 第四栈 [3, 4, 2, 1, 0, 0], # 第五栈 [4, 2, 3, 2, 0, 0] # 第六栈 ] con 2 origin_stack = [ [4, 4, 3, 0, 0, 0], # 第一栈…...
flutter app实现分辨率自适应的图片资源加载
在 Flutter 中,为了实现分辨率自适应的图片资源加载,确实需要遵循特定的目录结构和命名规则。这种机制允许 AssetImage 根据设备的 设备像素比(Device Pixel Ratio, DPR) 自动选择最合适的图片资源。以下是详细的说明和实现步骤&a…...
软件测试之测试数据生成(Excel版)
这是Excel生成测试数据的函数使用 1.时间 1.1.时间 例生成2022-05-01之前一年内任意时间点: =TEXT("2022-05-01"-RAND()-RANDBETWEEN(1,365),"yyyy-mm-dd hh:mm:ss")1.2.年月日 yyyy-mm-dd 以当前时间生成10年的日期 =TEXT(NOW()-RAND()-RANDBETWE…...
(51单片机)LCD显示数据存储(DS1302时钟模块教学)(LCD1602教程)(独立按键教程)(延时函数教程)(I2C总线认识)(AT24C02认识)
目录 演示视频: 源代码 main.c LCD1602.c LCD1602.h AT24C02.c AT24C02.h Key.c Key.h I2C.c I2C.h Delay.c Delay.h 代码解析与教程: Dealy模块 LCD1602模块 Key模块 I2C总线模块 AT24C02模块 /E2PROM模块 main模块 演示视频: &…...
STL简介 + string【上】
一 . STL简介 1.1 什么是STL STL(standard template libaray - 标准模板库) : 是C标准库的重要组成部分 , 不仅是一个可复用的组件库 , 而且是一个包罗 数据结构 与 算法 的软件框架 。 注意 : 是标准库的一部分 ÿ…...
【Bluedroid】A2DP Sink播放流程源码分析(二)
接上一篇继续分析:【Bluedroid】A2DP Sink播放流程源码分析(一)_安卓a2dp sink播放流程-CSDN博客 AVDTP接收端(Sink)流事件处理 bta_av_sink_data_cback 是 Bluedroid 中 A2DP Sink 角色的 AVDTP 数据回调函数,负责处理接收端的音频数据事件,将底层接收到的音频数据传递…...
redis利用备忘录
fofa: icon_hash"864611937" 防护: redis的安全设置:设置完毕,需要重加载配置文件启动redis 1.绑定内网ip地址进行访问 2. requirepass设置redis密码 3.保护模式开启protected-mode开启(默认开启) 4.最好把…...
SAP系统中MD01与MD02区别
知识点普及-MD01与MD02区别 1、从日常业务中,我们都容易知道MD01是运行全部物料,MD02是运行单个物料 2、在做配置测试中,也出现过MD02可以跑出物料,但是MD01跑不出的情况。 3、MD01与MD02的差异: 3.1、只要在物料主数…...
企业官网nodejs mySQL数据库安装及使用
以下是企业官网的MySQL数据库设计、本地安装指南,以及基于Node.js的增删改查(CRUD)实现方案: 一、MySQL数据库设计(企业官网基础表) 1. 核心表结构 -- 1. 用户表(管理员) CREATE T…...
Spring Boot自动配置原理深度解析:从条件注解到spring.factories
大家好!今天我们来深入探讨Spring Boot最神奇的特性之一——自动配置(Auto-configuration)。这个功能让Spring Boot如此受欢迎,因为它大大简化了我们的开发工作。让我们一起来揭开它的神秘面纱吧!👀 🌟 什么是自动配置…...
ubuntu学习day3
3 编译与调试 3.1 gcc/g编译器 当我们进行编译的时候,要使用一系列的工具,我们称之为工具链。SDK就是编译工具链的简写,我们所使用的是gcc系列编译工具链。使用-v参数来查看gcc的版本,从而确定某些语法特性是否可用,…...
