最小生成树小结
问题引入:
新兴城镇之间需要修建道路,两两城镇之间修建道路所需的花费是不一样的,在保证所有城镇相通的情况下,求最小花费。
这道题需要用到最小生成树的相关知识。
一、最小生成树的概念#
1. 最小生成树的定义#
在一个个点的无向连通图中,取条边,并使所有点相连,所得到的子图被称为原图的一棵生成树;在一个带权的无向连通图中各边权之和最小的一棵生成树即为原图的最小生成树。
2. 最小生成树的性质#
-
图中权值最小的边(如果唯一的话)一定在最小生成树上。
-
对于一个图,如果图中的边权值都不相同,则图的最小生成树是唯一的,反之亦然。
-
一个图,各个最小生成树的形态不同,但权值相同的边的数量一定相等。
3. 关于对性质3的证明#
在一个图中,,是它的两棵不同的最小生成树。组成的边为,组成的边为,现在我们需要证明,把,边的权值按从小到大排序后的序列是一样的,即对于所有,都有。
思考在第个位置,第一次出现了。
不妨设。
情况:在中,那么必存在,并且(因为是第一次出现不相同的边啊)。这时即有,所以,所以交换和的位置并不会影响的有序序列,两棵树在第号位置变成了一条边。
情况:不在中,考虑把它加入中,则形成了一个环,并且环上所有权值(不然就不是最小生成树)。也就是说,这个环上存在着另一条边不在中(如果在中就会形成环),且(是第一次出现不相同的边),。于是,,同样三者相等。那么我们就可以交换与,没有影响到的有序序列,然后转换成情况。
二、两种计算最小生成树的算法#
1. Prim算法#
贪心算法,原理略。
inline void Prim() {
memset(vis, 0, sizeof vis);
int s = n;
while(s --) {
minn = INF;
for (int i = 1;i <= n; ++i) {
if (!vis[i] && v[i] < minn) {
minn = v[i], pos = i;
}
}
vis[pos] = 1, ans += v[pos];
for (int i = 1;i <= n; ++i) {
if (!vis[i] && v[i] > dis[pos][i]) {
v[i] = dis[pos][i];
}
}
}
}
2. Kruskal算法#
同样的贪心算法,同样地略。
inline void Kruskal() {
sort_by_w(edg + 1, edg + 1 + m, cmp);//从小到大
for (int i = 1;i <= m; ++i) {
if(cnt >= n) return;
int x = edg[i].u, y = edg[i].v;
int fx = find(x), fy = find(y);
if (fx != fy) {
cnt ++;
ans += edg[i].w;
f[fx] = fy;
}
}
}
三、练手题目&一句话分析#
1. 黑暗城堡#
求最短路树计数,那先跑一遍,然后枚举每个点,乘法原理,就行了。
2. 北极通讯网络#
把题意转换下,就是叫你求第大最小生成树上的边,。
3. 构造完全图#
思考算法的流程,每次加边时,对答案的贡献应是。
4. 秘密的牛奶运输(严格次小生成树)#
先跑个最小生成树,然后考虑加入每条非树边,在形成的环上去掉一条最大边,当然,要保证严格次小,还需要保留次小边,用倍增实现。
5. 最小生成树计数#
有个性质:各个最小生成树的形态不同,但权值相同的边的数量一定相等。所以跑一遍最小生成树后直接暴力搜索,数据较小。
6. Tree#
二分给白边加偏移量,然后跑最小生成树。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!