首页 > 其他分享 >【图论】最小生成树

【图论】最小生成树

时间:2023-01-14 15:45:18浏览次数:28  
标签:图论 连通 int Kruskal 最小 生成 算法

定义及性质

如果连通图的一个子图是一棵包含所有顶点的树,则该子图称为其的生成树。

生成树是连通图的包含图中的所有顶点的极小连通子图,无环,只有 \(n-1\) 条边。

图的生成树不唯一。从不同的顶点出发进行遍历,可得到不同的生成树。

无向连通图的最小生成树为边权和最小的生成树。

算法实现

常见的最小生成树算法有 Kruskal 算法和 Prim 算法。

Kruskal 的时间复杂度为 \(O(m\log m)\) ,适合稀疏图

暴力 Prim 的时间复杂度为 \(O(n^2+m)\) ,适合于稠密图

堆优化 Prim 类似 Dijkstra 的堆优化,但如果使用二叉堆等不支持 \(O(1)\) decrease-key 的堆,复杂度就不优于 Kruskal ,常数也比 Kruskal 大。

一般情况下使用 Kruskal 算法。在稠密图尤其是完全图上,暴力 Prim 的复杂度比 Kruskal 优,但不一定实际跑得更快。

Kruskal 算法

Kruskal 算法能在 \(O(m\log m)\) 的时间内得到一个最小生成树,主要是基于贪心的思想:

  1. 将边按照边权从小到大排序,并建立一个没有边的图 \(T\) 。
  2. 选出一条没有被选过的边权最小的边。
  3. 如果这条边两个顶点在 \(T\) 中所在的连通块不相同,那么将它加入图 \(T\) ,相同就跳过。
  4. 重复 \(2\) 和 \(3\) 直到图 \(T\) 连通为止。

由于只需要维护连通性,不需要真正建立图 \(T\) ,可用并查集来维护。

\(Code:\)

#include<bits/stdc++.h>
using namespace std; 

const int N = 1e6;
int n, m, f[N], sum, num;
struct edge
{
	int u, v, w;
} e[N];

int read()
{
	int x = 0; bool s = 0; char c = getchar();
	while(c < '0' || c > '9') {if(c=='-') s = 1; c = getchar();}
	while('0' <= c && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}
	return s ? -x : x;
}

bool cmp(edge x, edge y) {return x.w < y.w;}

int find(int x) {return f[x] == x ? f[x] : f[x] = find(f[x]);}

bool Kruskal()
{
	sort(e + 1, e + m + 1, cmp);  // 将边权排序
	for(int i = 1; i <= m; i++)
	{
		int x = find(e[i].u), y = find(e[i].v);
		if(x == y) continue;  // 若两点已经联通,则不需要这条边
		f[x] = y;
		sum += e[i].w;
		if(++num == n - 1) return true;  // 若已构成一颗树,即边数为点数减一时,退出操作
	}
	return false;
}

int main()
{
	n = read(), m = read();
	for(int i = 1; i <= n; i++) f[i] = i;  // 初始化并查集
	for(int i = 1; i <= m; i++) e[i].u = read(), e[i].v = read(), e[i].w = read();
	if(Kruskal()) printf("%d", sum);
	else puts("orz");
	return 0;
}

标签:图论,连通,int,Kruskal,最小,生成,算法
From: https://www.cnblogs.com/5652fsft/p/mst.html

相关文章

  • Centos7 最小化安装网络配置
    Centos最小化安装真是”最小化”,什么都没有......
  • 使用Stable Diffusion和Pokedex的描述生成神奇宝贝图片
    还记得我们以前使用GAN、Clip、DALL-E生成神奇宝贝的文章吗,现在是时候使用StableDiffusion了在本文中,我将展示如何从神奇宝贝系列不同游戏中的Pokedex条目中获取神奇宝......
  • 洛谷 P3600 随机数生成器
    洛谷传送门设\(h_i\)为所有询问最大值\(\lei\)的方案数,则\(ans=\dfrac{\sum\limits_{i=1}^ni\times(h_i-h_{i-1})}{x^n}\)。设\(g_i\)为在\(1\simn\)......
  • 使用go自定义生成项目LISENSE(授权协议)
    需要使用一个使用go开发的工具,叫license,在Windows下安装这个工具,请确保你使用的gosdk是1.16以上的版本,然后执行下面的命令:goinstallgithub.com/nishanths/license/v5@......
  • dockerfile 将自己的nodeapi项目结合指定版本node环境打包生成全新的mynodeapi镜像
    用过宝塔或手动部署node-api项目就知道有多少时候是因为生产环境上node的版本与我们提交的node版本过高或过低导致无法运行的这几天玩docker随便把我原先的项目尝试打包......
  • Java生成和操作Excel文件 - 残星
    JAVAEXCELAPI:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容、创建新的Excel文件、更新已经存在的Excel文件。使用该API非Windows操作系统也可以通过纯......
  • 通关搜索和图论 day_16 -- Prim & Kruskal
    Prim先初始化距离,全部是正无穷,然后n次迭代,每次迭代执行:1.找到不在集合当中的距离最小的点(这里的集合是当前的生成树2.用这个点更新其他点到集合的距离举例,我们有......
  • 通关搜索和图论 day_17 -- 染色法 & 匈牙利算法
    染色法一个图是二分图当且仅当她可以被2染色(不含有奇数环)流程如下,先找到一个不在集合中的点把他放在左边然后遍历这个点有连接的点,把这些点放到右边,再依次遍历放到右......
  • 【题解】P4126 [AHOI2009]最小割
    题意求最小割和可行边和必须边。思路清真,清真,还是**的清真。考虑可行边的充要条件:满流不存在另一条\(u,v\)间的最短路,即在残量网络上不存在包含\(u,v\)......
  • react中二维码生成
    参考文档:https://blog.csdn.net/weixin_45022563/article/details/124843593 awesomeqr/react案例:注意需要给父级div设置高宽下载:yarnadd@awesomeqr/react......