算法 最小生成树

news2024/11/21 0:12:56

算法选择

稠密图:朴素版普利姆算法【因为代码短】

稀疏图:克鲁斯卡尔算法【因为思路简单】

普利姆(Prim)

朴素 Prim

时间复杂度 O(n^2)

适用情况

稠密图

算法流程

集合:当前已经在连通块中的所有点

  1. 初始化距离,将所有距离初始化为正无穷
  2. n 次迭代,因为要加入 n 个点

for(int i = 0; i < n; i ++)

找到集合外距离最近的点,赋给 t

用 t 更新其它点到集合的距离

把 t 加到集合中st[t] = true;

模板

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 510, INF = 0x3f3f3f3f;
int n, m;
int g[N][N];
int dist[N];
bool st[N];
int prim() {
	memset(dist, 0x3f, sizeof dist);//初始化所有距离
	int res = 0;//最小生成树中所有边之和
	for (int i = 0;i < n;i++) {//n次迭代
		int t = -1;
		for (int j = 1;j <= n;j++) {//找集合外距离最小的点
			if (!st[j] && (t == -1 || dist[t] > dist[j]))//t==-1说明现在还没有找到任何一个点
				t = j;//t存当前距离最小的点
		}
		if (i && dist[t] == INF)//如果不是第一个点并且dist[t]是正无穷,说明当前图是不连通的,说明不存在最小生成树
			return INF;
        if (i)//先累加,再更新,防止自环的加入
			res += dist[t];
		for (int j = 1;j <= n;j++)
			dist[j] = min(dist[j], g[t][j]);//dist表示该点到集合的距离
		st[t] = true;
	}
	return res;
}

例题——Prim求最小生成树

给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数。

求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。

给定一张边带权的无向图G=(V, E),其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。

由V中的全部n个顶点和E中n-1条边构成的无向连通子图被称为G的一棵生成树,其中边的权值之和最小的生成树被称为无向图G的最小生成树。

输入格式

第一行包含两个整数n和m。

接下来m行,每行包含三个整数u,v,w,表示点u和点v之间存在一条权值为w的边。

输出格式

共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。

数据范围

1≤n≤500,

1≤m≤10^5,

图中涉及边的边权的绝对值均不超过10000。

输入样例

4 5

1 2 1

1 3 2

1 4 3

2 3 2

3 4 4

输出样例

6

代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 510, INF = 0x3f3f3f3f;
int n, m;
int g[N][N];
int dist[N];
bool st[N];
int prim() {
	memset(dist, 0x3f, sizeof dist);//初始化所有距离
	int res = 0;//最小生成树中所有边之和
	for (int i = 0;i < n;i++) {//n次迭代
		int t = -1;
		for (int j = 1;j <= n;j++) {//找集合外距离最小的点
			if (!st[j] && (t == -1 || dist[t] > dist[j]))//t==-1说明现在还没有找到任何一个点
				t = j;//t存当前距离最小的点
		}
		if (i && dist[t] == INF)//如果不是第一个点并且dist[t]是正无穷,说明当前图是不连通的,说明不存在最小生成树
			return INF;
        if (i)//先累加,再更新,防止自环的加入
			res += dist[t];
		for (int j = 1;j <= n;j++)
			dist[j] = min(dist[j], g[t][j]);//dist表示该点到集合的距离
		st[t] = true;
	}
	return res;
}
int main() {
	scanf("%d%d", &n, &m);
	memset(g, 0x3f, sizeof g);
	while (m--) {
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		g[a][b] = g[b][a] = min(g[a][b], c);
	}
	int t = prim();
	if (t == INF)
		puts("impossible");//所有点不连通时不存在最小生成树
	else
		printf("%d\n", t);
	return 0;
}

堆优化 Prim

时间复杂度 O(mlogn)

适用情况

稀疏图

克鲁斯卡尔(Kruskal)

时间复杂度 O(mlogm)

适用情况

稀疏图

算法流程

  1. 将所有边按照权重从小到达排序,可以用快排排序 O(mlogm)
  2. 从小到大依次枚举每条边a,b,权重c O(m)

如果a,b不连通,那么将这条边加入集合中

模板

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 200010;
int n, m;
int p[N];
struct Edge {
	int a, b, w;
	bool operator<(const Edge& W)const {
		return w < W.w;
	}
}edges[N];
int find(int x) {
	if (p[x] != x)
		p[x] = find(p[x]);
	return p[x];
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0;i < m;i++) {
		int a, b, w;
		scanf("%d%d%d", &a, &b, &w);
		edges[i] = { a,b,w };
	}
    //克鲁斯卡尔算法
	sort(edges, edges + m);//将所有边按权重排序
	for (int i = 1;i <= n;i++)//初始化并查集
		p[i] = i;
	int res = 0, cnt = 0;
	for (int i = 0;i < m;i++) {//从小到大枚举所有边
		int a = edges[i].a, b = edges[i].b, w = edges[i].w;
		a = find(a), b = find(b);
		if (a != b) {//两个祖宗节点不连通
			p[a] = b;//合并两个集合
			res += w;//res存最小生成树中所有树边权重之和
			cnt++;//cnt存当前加了多少条边
		}
	}
	if (cnt < n - 1)//不连通
		puts("impossible");
	else
		printf("%d\n", res);
	return 0;

}

例题——Kruskal求最小生成树

题目描述

给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数。

求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。

给定一张边带权的无向图G=(V, E),其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。

由V中的全部n个顶点和E中n-1条边构成的无向连通子图被称为G的一棵生成树,其中边的权值之和最小的生成树被称为无向图G的最小生成树。

输入格式

第一行包含两个整数n和m。

接下来m行,每行包含三个整数u,v,w,表示点u和点v之间存在一条权值为w的边。

输出格式

共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。

数据范围

1≤n≤10^5,

1≤m≤2∗10^5,

图中涉及边的边权的绝对值均不超过1000。

输入样例

4 5

1 2 1

1 3 2

1 4 3

2 3 2

3 4 4

输出样例

6

代码

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 200010;
int n, m;
int p[N];
struct Edge {
	int a, b, w;
	bool operator<(const Edge& W)const {
		return w < W.w;
	}
}edges[N];
int find(int x) {
	if (p[x] != x)
		p[x] = find(p[x]);
	return p[x];
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0;i < m;i++) {
		int a, b, w;
		scanf("%d%d%d", &a, &b, &w);
		edges[i] = { a,b,w };
	}
	sort(edges, edges + m);
	for (int i = 1;i <= n;i++)
		p[i] = i;
	int res = 0, cnt = 0;
	for (int i = 0;i < m;i++) {
		int a = edges[i].a, b = edges[i].b, w = edges[i].w;
		a = find(a), b = find(b);
		if (a != b) {
			p[a] = b;
			res += w;//res存最小生成树中所有树边权重之和
			cnt++;//cnt存当前加了多少条边
		}
	}
	if (cnt < n - 1)
		puts("impossible");
	else
		printf("%d\n", res);
	return 0;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1294048.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JNPF低代码平台详解 -- 系统架构

目录 一、技术介绍 技术架构 二、设计原理 三、界面展示 1.代码生成器 2.工作流程 3.门户设计 4.大屏设计 5.报表设计 6.第三方登录 7.多租户实现 8.分布式调度 9.消息中心 四、功能框架 JNPF低代码是一款新奇、实用、高效的企业级软件开发工具&#xff0c;支持企…

在 JavaScript 中导入和导出 Excel XLSX 文件:SpreadJS

在 JavaScript 中导入和导出 Excel XLSX 文件 2023 年 12 月 5 日 使用 MESCIUS 的 SpreadJS 将完整的 JavaScript 电子表格添加到您的企业应用程序中。 SpreadJS 是一个完整的企业 JavaScript 电子表格解决方案&#xff0c;用于创建财务报告和仪表板、预算和预测模型、科学、工…

文章解读与仿真程序复现思路—— 中国电机工程学报EI\CSCD\北大核心《考虑多重不确定性的电–气–交通网络耦合系统数据驱动鲁棒优化调度》

这个标题涉及到一个复杂系统的问题&#xff0c;以下是对标题的解读&#xff1a; 电–气–交通网络耦合系统&#xff1a; 涉及电力系统、气体&#xff08;可能是天然气&#xff09;系统和交通网络之间的相互关系。这种耦合可能表示这些系统之间存在一定的依赖和相互影响。 多重不…

Java面试题(每天10题)-------连载(45)

Dubbo篇 1、Dubbo的服务调用流程 2、Dubbo支持那种协议&#xff0c;每种协议的应用场景&#xff0c;优缺点&#xff1f; dubbo&#xff1a; 单一长连接和 NIO 异步通讯&#xff0c;适合大并发小数据量的服务调用&#xff0c;以及消费者远大于提供者。传输协议 TCP&#xff0c;…

PbootCMS 前台RCE漏洞复现

0x01 产品简介 PbootCMS是全新内核且永久开源免费的PHP企业网站开发建设管理系统,是一套高效、简洁、 强悍的可免费商用的PHP CMS源码,能够满足各类企业网站开发建设的需要 0x02 漏洞概述 PbootCMS v<=3.1.6版本中存在模板注入,攻击者可构造特定的链接利用该漏洞,执行…

微信小程序引入vant-weapp爬出坑

最新的微信小程序的项目结构跟之前的不一样&#xff0c;然后&#xff0c;按照vant-weapp上的官方文档&#xff0c;安装步骤失败&#xff0c;提示了各种错误。如果你的微信小程序结构跟我的一致&#xff0c;可以采用和我一样的方案。 微信小程序引入vant-weapp爬出坑 移动pack…

基于javeweb实现的图书借阅管理系统

一、系统架构 前端&#xff1a;jsp | js | css | jquery 后端&#xff1a;servlet | jdbc 环境&#xff1a;jdk1.7 | mysql | tocmat 二、代码及数据库 三、功能介绍 01. 登录页 02. 首页 03. 图书管理 04. 读者管理 05. 图书分类管理 06. 图书借阅信息 07. 图书归还信…

H桥简单24V直流电机GPIO驱动代码

主控: 雅特力AT32F403A, 主频100Mhz 驱动: GPIO口简单驱动 先展示主要的桥电路 头文件 /**************************************************************************** Copyright notice & Disclaimer* *******************************************…

Mysql dumpling 导入导出sql文件

一&#xff1a;导出命令 mysqldump -u root -p saishi > saishi.sql mysqldump -u root -p saishi > saishi.sql root是用户名 saishi是数据库名 saishi.sql导出文件名 二&#xff1a;选择导入的数据库 cd到安装mysql的文件下&#xff08;找不到可以用&#xff1a;wh…

TCP一对一通信

package 二十一章; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner;/*** Socket服务端**/ public class SocketServer {public static void main(String[] args) {ServerSocket ss null;Socket s null;try {// 创建监听…

BPM、ERP、OA 各自的功能和特点是什么?怎么配合使用?

OA、BPM、ERP几乎是任何一家企业都会接触到的信息管理系统及程序。 首先&#xff0c;我从定义上理清BPM、ERP和OA ERP(Enterprise Resource Planning,企业资源计划)&#xff0c;一般围绕供应链、生产制造和财务为核心。 BPM&#xff08;business process management&#xf…

JavaSE基础50题:10. 计算1/1-1/2+1/3-……+1/99-1/100的值(两种方法)

概述 计算1/1 - 1/2 1/3 - …… 1/99 - 1/100的值。 当分母为偶数时&#xff0c;符号是负的&#xff0c;放分母为奇数时&#xff0c;符号是负的。 方法一 用 flg 做了一个正负交替 【代码】 public static double func() {double sum 0;int flg 1; //设置正负号的for (i…

2021年第十届数学建模国际赛小美赛A题气道阻力的评估解题全过程文档及程序

2021年第十届数学建模国际赛小美赛 A题 气道阻力的评估 原题再现&#xff1a; 气道阻力的定义是通过肺气道产生单位气流所需的经肺压力的变化。更简单地说&#xff0c;它是嘴和肺泡之间的压力差&#xff0c;除以气流。影响气道阻力的因素是多方面的&#xff0c;我们需要探讨这…

大数据分析与应用实验任务十一

大数据分析与应用实验任务十一 实验目的 通过实验掌握spark Streaming相关对象的创建方法&#xff1b; 熟悉spark Streaming对文件流、套接字流和RDD队列流的数据接收处理方法&#xff1b; 熟悉spark Streaming的转换操作&#xff0c;包括无状态和有状态转换。 熟悉spark S…

探索Spring事件监听机制的奇妙世界

文章目录 什么是Spring事件监听机制主要组件内置的事件监听类自定义事件监听类总结 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 什么是Spring事件监听机制 Spring事件监听机制是Spr…

【网络安全】零日漏洞(0day)是什么?如何防范零日攻击?

零日攻击是利用零日漏洞&#xff08;0day&#xff09;对系统或软件应用发动的网络攻击&#xff0c;近年来&#xff0c;零日攻击威胁在日益增长且难以防范&#xff0c;零日攻击已成为企业网络信息安全面临的最严峻的威胁之一。 文章目录 What is a zero-day attack&#xff1f;…

计算机操作系统4

1.什么是进程同步 2.什么是进程互斥 3.进程互斥的实现方法(软件) 4.进程互斥的实现方法(硬件) 5.遵循原则 6.总结&#xff1a; 线程是一个基本的cpu执行单元&#xff0c;也是程序执行流的最小单位。 调度算法&#xff1a;先来先服务FCFS、短作业优先、高响应比优先、时间片…

用 Bytebase 做数据库 schema 迁移

数据库 schema 迁移指修改管理数据库结构的变更&#xff0c;包括为数据库添加视图或表、更改字段类型或定义新约束。Bytebase 提供了可视化 GUI 方便迁移数据库 schema&#xff0c;本教程将展示如何使用 Bytebase 为 schema 迁移配上 SQL 审核&#xff0c;自定义审批流&#xf…

浅谈城镇老旧小区改造中电动汽车充电桩应用探讨

摘要&#xff1a;《2020 年政府工作报告》指出&#xff1a;加强新型基础设施建设&#xff0c;发展新一代信息网络&#xff0c;拓展 5G 应用&#xff0c;建设数据中心&#xff0c;增加充电桩、换电站等设施&#xff0c;推广新能源汽车&#xff0c;激发新消费需求、助力产业升级。…

【天线了解】2.WTW天线了解与使用

注意网段&#xff1a;&#xff08;计算机与设备同一网段才可以通信&#xff09; 1.LS28接收机使用的网段是192.168.16.X&#xff0c;所以电脑应该同样设置 2.WTW天线使用网段192.168.98.X 0.WTW使用原理 1.计算机控制LS28&#xff08;接收机&#xff09;&#xff0c;WTW天线。 …