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

20251213 - 最小生成树

生成树

生成树,就是在一个无向连通图中选择 \(n - 1\) 条边,使得这 \(n-1\) 条边构成了一棵树。

最小生成树

假设每一条边有边权,边权和最小的生成树就是最小生成树(MST)。

求法

1. Prim

这是一个点核心的算法。

每次选择点权最小的点,在扩展到邻居节点,这和 dijkstra 几乎一毛一样。

朴素时间复杂度:\(O(n^2+m)\)

堆优化:\(O((n+m)\log_2m)\)

平衡树优化(实测更快一点):\(O((n+m)log_2m)\)

代码:

int Prim() {int ans = 0;priority_queue <Node> q;vector <int> dist(n + 1, inf), vis(n + 1, 0);dist[s] = 0;q.push({s, 0});while (!q.empty()) {int u = q.top().v, w = q.top().w;q.pop();if (vis[u]) continue;vis[u] = 1;ans += w;for (auto nxt : edges[u]) {int v = nxt.v, w = nxt.w;if (w < dist[v]) {dist[v] = w;q.push({v, dist[v]});}} }return ans;
}

2.kruskal

这是一个边核心的算法。

每次选择边权最小的边,在判断有没有环。

怎么判断有没有环呢?

Tarjan DSU!

代码:

int kruskal() {vector <TreeNode> edges;n = read(), m = read();for (int i = 1; i <= n; i++) fa[i] = i;for (int i = 1; i <= m; i++) {int x = read(), y = read(), w = read();edges.push_back({x, y, w});}sort(edges.begin(), edges.end());int ans = 0, tot = 0;;for (auto [x, y, w] : edges) { // C++17x = find(x), y = find(y);if (x != y) {fa[x] = y;ans += w;tot++;}} 
}

例题:

C - 营救

跑一下 kruskal,如果 find(s) == find(t) 直接输出即可。

#include <bits/stdc++.h>using namespace std;
#define ll long long
#define ull unsigned long long
#define db double
#define sz(x) ((int)x.size())
#define inf (1 << 30)
#define pb push_back
typedef pair<int, int> PII;
const int N = 1e5 + 7;
const int P = 998244353;
int read() {int x = 0, f = 1;char ch = getchar();while (!(ch >= '0' && ch <= '9')) {if (ch == '-') f = -f;ch = getchar();}while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;
}
int n, m, fa[N], s, t;
struct TreeNode {int x, y, w;bool operator < (const TreeNode &A) const {return w < A.w;}
};
vector <TreeNode> edges;
int find(int x) {return fa[x] == x ? x : fa[x] = find(fa[x]);
}
int main() {n = read(), m = read(), s = read(), t = read();for (int i = 1; i <= n; i++) fa[i] = i;for (int i = 1; i <= m; i++) {int x = read(), y = read(), w = read();edges.push_back({x, y, w});}sort(edges.begin(), edges.end());int ans = inf, tot = 0;;for (auto [x, y, w] : edges) {x = find(x), y = find(y);if (x != y) {fa[x] = y;tot++;if (find(s) == find(t)) {ans = min(ans, w);}}} printf("%d\n", ans);return 0;
}

D - Out of Hay S

就是求一个 max 即可。

E - 买礼物

把每一个优惠边权设成 A,再把不优惠连向 0 号点,再搞一遍 MST。

后记

警钟敲烂:在写并查集时请不要带 \(\log\)!!!

http://www.jsqmd.com/news/84308/

相关文章:

  • ISC-3000S的U-Boot 镜像头部解析
  • 实战干货:影刀RPA一键生成小红书竞品分析报告,效率飙升[特殊字符]
  • 影刀RPA×AI双剑合璧!小红书商品笔记自动发布,效率飙升50倍![特殊字符]
  • 基于Java的安全检查巡视智慧管理系统的设计与实现全方位解析:附毕设论文+源代码
  • 基于Java的安全生产智经营理系统的设计与实现全方位解析:附毕设论文+源代码
  • MarkDown指令学习
  • 还在手动上架TikTok商品?影刀RPA一键搞定,效率提升500%[特殊字符]
  • 基于Java的安全生产检查统计分析智慧管理系统的设计与实现全方位解析:附毕设论文+源代码
  • 3步打造Switch专属开机动画:让你的主机从启动就与众不同
  • 影刀RPA×AI双剑合璧!小红书笔记评论数据智能提取,3分钟搞定全天分析![特殊字符]
  • LLM - MCP Powered Agent_从工具失配到架构重构的实战指南
  • 重练算法(代码随想录版) day39 - 动态规划part7
  • 影刀RPA×AI强强联合!小红书限时折扣活动一键创建,效率提升40倍![特殊字符]
  • LLM - 从 Prompt 到上下文工程:面向 Java 的生产级 AI Agent 设计范式
  • AtCoder Beginner Contest 436 ABCDEF 题目解析
  • 基于储能稳压的交直流混合电能路由器Matlab/Simulink仿真
  • 北京上门收酒服务权威推荐榜单 - 品牌排行榜单
  • 2025中餐适配的厨余处理器测评:七大品牌研磨精度与管道保护能力对比 - 速递信息
  • AI元人文构想:元协议、行为重塑与文明免疫系统——通往意义原生的智能未来
  • VinylMusicPlayer:Android 开源音乐播放器完整使用指南
  • Vue脚手架快速搭建指南
  • CSS 选择器
  • 影刀RPA×AI强强联合!小红书笔记转化数据智能分析,3分钟洞察爆款密码![特殊字符]
  • 2025免费降AI率完全指南:从工具选择到实操技巧,一步到位
  • 2025免费降AI率完全指南:从降AI工具选择到实操技巧,一步到位!
  • 国产操作系统:自主可控的技术突围
  • 发电。
  • 10398_基于SSM的教学评价管理系统
  • 鸿蒙PC UI控件库 - 品牌标识系统详解
  • test tags - itnews