图论——最小生成树的扩展应用

ops/2025/2/6 22:35:55/


最小生成树相关原理

acwing1146.新的开始

假设存在一个“超级发电站”
在每一个矿井修发电站相当于从这个“超级发电站”到各个矿井连一条长度为 v [ i ] v[i] v[i]的边。
这样一来这就是一个最短路的模板题。

#include <iostream>
#include <cstring>
using namespace std;
const int N = 310;
int dist[N];
bool st[N];
int w[N][N];
int n;
int prim()
{memset(dist, 0x3f, sizeof dist);dist[0] = 0;int res = 0;for (int i = 0; i < n + 1; i ++ ){int t = -1;for (int j = 0; j < n + 1; j ++ ){if (!st[j] && (t == -1 || dist[t] > dist[j]))t = j;}st[t] = 1;res += dist[t];for (int j = 0; j < n + 1; j ++ )dist[j] = min(dist[j], w[t][j]);}return res;
}
int main()
{cin >> n;for (int i = 1; i <= n; i ++ ){cin >> w[0][i];w[i][0] = w[0][i];}for (int i = 1; i <= n; i ++ )for (int j = 1; j <= n; j ++ )cin >> w[i][j];printf("%d", prim());return 0;
}

acwing1145.北极通讯网络

假设有给定一个 d d d值,将任意两个长度小于等于 d d d的点都进行集合合并,形成 m m m个连通块( m m m 棵最小生成树),则需要 m m m个卫星设备
即找一个最小的 d d d值,使得将所有权值大于 d d d的边删去,之后,整个图形的连通块的个数等于 k k k

显然,连通块的数量和d取值会满足以下这种关系。
在这里插入图片描述
我们考虑kruskal算法,kruskal算法是从大到小枚举每个边,如果该边两端不连通则加入该边,当我们当前枚举的边权为d时,虽然实际上我们只是在小于等于d的边权中选择将能够实现联通的边加入了最小生成树生成了若干连通块,然而实际上这和把边权小于等于d的边全部连起来形成连通块的情况是相同的,也正因此我们上面这个问题和kruskal算法实际上是等价的,我们可以用kruskal算法来做。

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
const int N = 510, M = N * N / 2;
int fa[N];
int m = 0, cnt;
struct Edge{int a, b;double w;bool operator< (const Edge &t) const{return w < t.w;}
}e[M];
PII q[N];
int n, k;
double get_dist(PII a, PII b)
{double dx = a.x - b.x;double dy = a.y - b.y;return sqrt(dx * dx + dy * dy);
}
int find(int a)
{return fa[a] == a ? a : fa[a] = find(fa[a]);
}
int main()
{double res = 0;cin >> n >> k;for (int i = 1; i <= n; i ++ )fa[i] = i;for (int i = 1; i <= n; i ++ )cin >> q[i].x >> q[i].y;for (int i = 1; i <= n; i ++ )for (int j = 1; j < i; j ++ )e[++ m] = {i, j, get_dist(q[i], q[j])};cnt = n;sort(e + 1, e + m + 1);for (int i = 1; i <= m; i ++ ){int a = find(e[i].a), b = find(e[i].b);double w = e[i].w;if (cnt <= k) break;if (a == b) continue;fa[a] = b;res = w;cnt -- ;}printf("%.2lf\n", res);return 0;
}

acwing346.走廊泼水节

做法:初始时先将每一个点看成一个大小为1的连通块,这个连通块就可以看成一个完全图(因为只有一个点)
做Kruskal算法,在每循环到一条可以合并两个连通块的边 e e e时,记 e e e的边长为 w w w,为了形成一个完全图,就要使得两个已经是完全图的连通块中的点有边,但是为了使最后的唯一最小生成树还是原来那棵而且,新增的边一定要大于 w w w
假设新边小于 w w w,因为新增边后会成环,当断开边 e e e,形成的树大小会变小,即不是原来那棵,所以不成立
假设新边等于 w w w,同样的断开 e e e,会形成一个大小一样但结构不一样的树,不满足唯一,所以也不成立。
这里我们新增的边权可以为 w + 1 w+1 w+1,因为我们的边权为从小到大枚举,也正因此 w + 1 w+1 w+1不会影响左右两个连通块内部最小生成树的情况。

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 6010, M = N * N / 2;
int fa[N];
int sz[N];
struct Edge{int a, b, w;bool operator< (const Edge &t) const{return w < t.w;}
}e[M];
int find(int x)
{return fa[x] == x ? x : fa[x] = find(fa[x]);
}
int t;
int main()
{cin >> t;while (t -- ){int n;cin >> n;for (int i = 1; i < n; i ++ ){int a, b, w;cin >> a >> b >> w;e[i] = {a, b, w};}sort(e + 1, e + n);for (int i = 1; i <= n; i ++ ){sz[i] = 1;fa[i] = i;}int res = 0;for (int i = 1; i < n; i ++ ){int a = find(e[i].a), b = find(e[i].b), w = e[i].w;if (a == b) continue;res += (sz[a] * sz[b] - 1) * (w + 1);sz[b] += sz[a];fa[a] = b;}cout << res << endl;}return 0;
}

acwing1148.秘密的牛奶运输

次小生成树的求解方式:
在这里插入图片描述
题解来源:https://www.acwing.com/solution/content/80131/

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 510, M = 10010;
struct Edge{int a, b, w;bool flag;bool operator< (const Edge &t) const{return w < t.w;}
}edge[M];
int fa[N];
int n, m;
int dist1[N][N], dist2[N][N];
int h[N], e[2 * N], ne[2 * N], w[2 * N], tot;
int find(int x)
{return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void add(int a, int b, int c)
{e[tot] = b, ne[tot] = h[a], w[tot] = c, h[a] = tot ++ ;
}
void dfs(int u, int fa, int maxd1, int maxd2, int d1[], int d2[])
{for (int i = h[u]; ~i; i = ne[i]){int j = e[i];if (j == fa) continue;if (w[i] > maxd1){d1[j] = w[i], d2[j] = maxd1;dfs(j, u, w[i], maxd1, d1, d2);}else if (w[i] < maxd1 && w[i] > maxd2){d1[j] = maxd1, d2[j] = w[i];dfs(j, u, maxd1, w[i], d1, d2);}else{d1[j] = maxd1, d2[j] = maxd2;dfs(j, u, maxd1, maxd2, d1, d2);}}return ;
}
int main()
{cin >> n >> m;for (int i = 1; i <= m; i ++ ){int a, b, w;cin >> a >> b >> w;edge[i] = {a, b, w};}for (int i = 1; i <= n; i ++ )fa[i] = i;sort (edge + 1, edge + 1 + m);memset(h, -1, sizeof h);ll sum = 0;for (int i = 1; i <= m; i ++ ){int a = edge[i].a, b = edge[i].b, w = edge[i].w;int aa = find(a), bb = find(b);if (aa != bb){fa[aa] = bb;sum += w;edge[i].flag = 1;add(a, b, w), add(b, a, w);}}for (int i = 1; i <= n; i ++ )dfs(i, -1, 0, 0, dist1[i], dist2[i]);ll res = 1e18;for (int i = 1; i <= m; i ++ ){if (edge[i].flag) continue;int a = edge[i].a, b = edge[i].b, w = edge[i].w;if (w > dist1[a][b]) res = min(res, sum + w - dist1[a][b]);else if (w > dist2[a][b]) res = min(res, sum + w - dist2[a][b]);}cout << res;return 0;
}

http://www.ppmy.cn/ops/156269.html

相关文章

短链接项目02---依赖的添加和postman测试

文章目录 1.声明2.对于依赖的引入和处理2.1原有的内容说明2.2添加公共信息2.3dependencies和management区别说明2.4添加spring-boot依赖2.5数据库的相关依赖2.6hutool工具类的依赖添加2.7测试test 的依赖添加 3.core文件的代码3.1目录层级结构3.2启动类3.3testcontroller测试类…

HTML基本语法

什么是HTML? HTML是超文本标记语言&#xff08;HyperText Markup Language&#xff09;的缩写&#xff0c;是一种用于创建网页的标准标记语言。HTML允许网页设计师通过使用标签来描述网页的结构和内容。 W3C标准 W3C&#xff08;World Wide Web Consortium&#xff09;是一…

机器学习之数学基础:线性代数、微积分、概率论 | PyTorch 深度学习实战

前一篇文章&#xff0c;使用线性回归模型逼近目标模型 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课&#xff1a;引领人工智能新时代【梗直哥瞿炜】 线性代数、微积分、概率论 …

Mac M1 ComfyUI 中 AnyText插件安装问题汇总?

Q1&#xff1a;NameError: name ‘PreTrainedTokenizer’ is not defined ? 该项目最近更新日期为2024年12月&#xff0c;该时间段的transformers 版本由PyPI 上的 transformers 页面 可知为4.47.1. A1: transformers 版本不满足要求&#xff0c;必须降级transformors &#…

网络安全--边界安全

现在人们生活依赖互联网程度越来越高&#xff0c;网络安全也逐步进入人们日常视野&#xff0c;信用卡信息泄漏、开房记录被查询、商业机密泄漏等等&#xff1b;无不牵动着一个人、一个公司、甚至一个国家的神经。随着技术的发展&#xff0c;网络边界变得也越来越复杂&#xff0…

【Redis】主从模式,哨兵,集群

主从复制 单点问题&#xff1a; 在分布式系统中&#xff0c;如果某个服务器程序&#xff0c;只有一个节点&#xff08;也就是一个物理服务器&#xff09;来部署这个服务器程序的话&#xff0c;那么可能会出现以下问题&#xff1a; 1.可用性问题&#xff1a;如果这个机器挂了…

php的使用及 phpstorm环境部署

php语法 环境搭建&#xff1a;在小皮中新建网站&#xff0c;注意先填写域名再点击选择根目录。 成功创建网站后&#xff0c;打开发现forbidden&#xff0c;因为新建的网站里是空的&#xff0c;需要新建index.php文件----> 在Phpstorm中左上角打开文件&#xff0c;打开那个文…

4 Hadoop 面试真题

4 Hadoop 面试真题 1. Apache Hadoop 3.0.02. HDFS 3.x 数据存储新特性-纠删码Hadoop面试真题 1. Apache Hadoop 3.0.0 Apache Hadoop 3.0.0在以前的主要发行版本&#xff08;hadoop-2.x&#xff09;上进行了许多重大改进。 最低要求的Java版本从Java 7增加到Java 8 现在&…