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

算法日记20:SC72最小生成树(prim朴素算法)

一、题目:

在这里插入图片描述

二、题解

在这里插入图片描述

2.1:朴素prim的步骤解析 O ( n 2 ) O(n^2) O(n2)(n<=1e3)

0、假设,我们现在有这样一个有权图

在这里插入图片描述

1、我们随便找一个点,作为起点开始构建最小生成树(一般是1号),并且存入intree[]状态数组中(该数组表示是否访问过了)

在这里插入图片描述

2、找所有点当中,距离intree[]最近的点,

  • 循环 n − 1 n-1 n1(因为已经确定了1这个点),每次找距离intree[]最近的点作为拓展点,
  • 即选择了[2]这个点
    在这里插入图片描述

3、把dis[2](2距离intree的距离)累计起来(res+=dis[2]),并且更新所有点的dis

在这里插入图片描述

4、此时,重复找所有点当中,距离intree[]最近的点(重复2/3)…

三、朴素prim代码解析

3.1、代码分块解析:

这段代码实现了 Prim 算法 用于求解 最小生成树,我会将代码分块并逐步解释每一块的作用。

1. 常量定义

const int N = 103;  // 设置最大点数
int a[N][N], dis[N];
bool st[N];
int n, m;

解释:

  • N 定义了图中点的最大数量,设置为 103。
  • a[N][N]:一个二维数组,表示图的邻接矩阵,存储两点之间的边权。
    • a[i][j]:表示i–>j的距离
  • dis[N]:一个一维数组,表示从起始点到每个节点的最短距离。
  • st[N]:布尔型数组,用来标记某个节点是否已经被加入最小生成树。(图解中的intree数组)
  • nm:分别表示图中的节点数和边数。

2. solve 函数的初始化

void solve()
{memset(dis, 0x3f, sizeof(dis));  // 初始化dis数组,设为最大值memset(a, 0x3f, sizeof(a));      // 初始化邻接矩阵为最大值// 初始化cin >> n >> m;for (int i = 1; i <= m; i++) {int ui, vi, wi;cin >> ui >> vi >> wi;    a[ui][vi] = min(a[ui][vi], wi);a[vi][ui] = min(a[vi][ui], wi);}for (int i = 1; i <= n; i++) a[i][i] = 0;  // 自己到自己没有边,权重为 0

解释:

  • memset(dis, 0x3f, sizeof(dis)):将 dis 数组初始化为一个较大的值(通常为无穷大,表示尚未连接的节点)。
  • memset(a, 0x3f, sizeof(a)):将邻接矩阵 a 初始化为无穷大,表示两点之间如果没有边,则权重为无穷大。
  • 输入节点数 n 和边数 m,然后读入每条边的信息,更新邻接矩阵 a。同时,因为有可能存在重复边,所以采用 min 取最小边权,确保保存的是权重最小的边。
  • 设置每个节点到自身的距离为 0

3. 最小生成树的 Prim 算法核心部分

   dis[1] = 0;  // 从节点1开始,初始权重为0int res = 0;  // 记录最小生成树的总权重for (int i = 1; i <= n; i++) // 进行n次选择最小值操作{  int temp = -1;  // 用于记录当前最小值对应的节点// 遍历所有节点,找出距离最小的未加入最小生成树的节点for (int j = 1; j <= n; j++) {  //和Dijkstra一样,//1.当j这个点还没访问过,2.遍历的的点j<当前点temp的距离,那么就更新temp//temp==-1只是为了确保其能够第一次进入循环,详解看Dijkstraif (!st[j] && ((temp == -1) || (dis[j] < dis[temp]))) {temp = j;}}//此时temp就是距离intree最近的点if (temp == -1) // 如果所有节点都已经被选中,说明图不连通,直接return{  cout << -1 << '\n';return; }

解释:

  • 初始化 dis[1] = 0,表示从节点 1 开始构建最小生成树,起始点的距离为 0
  • res 用来记录最小生成树的总权重。
  • 外层 for (int i = 1; i <= n; i++) 进行 n 次选择最小值操作,每次选择一个最小的未加入最小生成树的节点。
  • 内层循环 for (int j = 1; j <= n; j++) 遍历所有节点,找出距离当前生成树最近的节点。条件是节点未加入生成树 !st[j]dis[j] 小于当前最小值。
  • temp == -1 用来判断是否图不连通。如果没有找到最小值节点,说明图是断开的,输出 -1

4. 更新最小生成树的权重并松弛边

       res += dis[temp];  // 将当前最小值加到结果中st[temp] = true;    // 标记节点temp已加入最小生成树dis[temp] = 0;      // 当前节点到自己的距离设为0(实际上不影响结果)for (int i = 1; i <= n; i++) {  // 松弛与temp相连的所有边if (!st[i]) {  // 只有未加入最小生成树的节点才能被松弛dis[i] = min(dis[i], a[temp][i]);} }    }cout << res << '\n';  // 输出最小生成树的总权重
}

解释:

  • 将选中的最小值节点 temp 的距离 dis[temp] 加到总权重 res 中。
  • 标记该节点已经被加入最小生成树,即 st[temp] = true
  • 进行 松弛操作,尝试更新与当前最小值节点相连的所有边的权重,更新未加入生成树的节点的最短距离 dis[i]

3.2、完整代码

#include<bits/stdc++.h>
using namespace std;const int N=103;
struct node{int v;//指向点int w;//权重
};
int a[N][N],dis[N];
bool st[N];
int n,m;void solve()
{memset(dis,0x3f,sizeof(dis));memset(a,0x3f,sizeof(a));//初始化cin>>n>>m;for(int i=1;i<=m;i++){int ui,vi,wi;cin>>ui>>vi>>wi;    //g[ui].push_back({vi,wi});a[ui][vi]=min(a[ui][vi],wi);a[vi][ui]=min(a[vi][ui],wi);}for(int i=1;i<=n;i++) a[i][i]=0;dis[1]=0; //从1开始,1的权重为0int res=0;for(int i=1;i<=n;i++)   //找n次最小值{int temp=-1;    //表示dis最小点for(int j=1;j<=n;j++)   //遍历每个点找最小值{//如果j还没被选中过if(!st[j] && ((temp==-1)||(dis[j]<dis[temp]))){temp=j;}}if (temp == -1) // 如果没有点可选,说明图不连通{cout<<-1<<'\n';break; }//此时表示已经选中了最小值tempres+=dis[temp];st[temp]=true;dis[temp]=0;//距离设置为0for(int i=1;i<=n;i++)    //松弛temp相连的边a[temp][i]{if(!st[i]) //表示i话没有松弛过{dis[i]=min(dis[i],a[temp][i]);} }    }cout<<res<<'\n';
} int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int _=1;while(_--) solve();return 0;
}

相关文章:

算法日记20:SC72最小生成树(prim朴素算法)

一、题目&#xff1a; 二、题解 2.1&#xff1a;朴素prim的步骤解析 O ( n 2 ) O(n^2) O(n2)(n<1e3) 0、假设&#xff0c;我们现在有这样一个有权图 1、我们随便找一个点&#xff0c;作为起点开始构建最小生成树(一般是1号)&#xff0c;并且存入intree[]状态数组中&#xf…...

玩转SpringCloud Stream

背景及痛点 现如今消息中间件(MQ)在互联网项目中被广泛的应用&#xff0c;特别是大数据行业应用的特别的多&#xff0c;现在市面上也流行这多个消息中间件框架&#xff0c;比如ActiveMQ、RabbitMQ、RocketMQ、Kafka等&#xff0c;这些消息中间件各有各的优劣&#xff0c;但是想…...

嵌入式经常用到串口,如何判断串口数据接收完成?

说起通信&#xff0c;首先想到的肯定是串口&#xff0c;日常中232和485的使用比比皆是&#xff0c;数据的发送、接收是串口通信最基础的内容。这篇文章主要讨论串口接收数据的断帧操作。 空闲中断断帧 一些mcu&#xff08;如&#xff1a;stm32f103&#xff09;在出厂时就已经在…...

iOS App的启动与优化

App的启动流程 App启动分为冷启动和热启动 冷启动&#xff1a;从0开始启动App热启动&#xff1a;App已经在内存中&#xff0c;但是后台还挂着&#xff0c;再次点击图标启动App。 一般对App启动的优化都是针对冷启动。 App冷启动可分为三个阶段&#xff1a; dyld&#xff1a…...

导出指定文件夹下的文件结构 工具模块-Python

python模块代码 import os import json import xml.etree.ElementTree as ET from typing import List, Optional, Dict, Union from pathlib import Path class DirectoryTreeExporter:def __init__(self,root_path: str,output_file: str,fmt: str txt,show_root: boo…...

Leetcode - 周赛436

目录 一、3446. 按对角线进行矩阵排序二、3447. 将元素分配给有约束条件的组三、3448. 统计可以被最后一个数位整除的子字符串数目四、3449. 最大化游戏分数的最小值 一、3446. 按对角线进行矩阵排序 题目链接 本题可以暴力枚举&#xff0c;在确定了每一个对角线的第一个元素…...

【pytest】编写自动化测试用例命名规范README

API_autoTest 项目介绍 1. pytest命名规范 测试文件&#xff1a; 文件名需要以 test_ 开头或者以 _test.py 结尾。例如&#xff0c;test_login.py、user_management_test.py 这样的命名方式&#xff0c;pytest 能够自动识别并将其作为测试文件来执行其中的测试用例。 测试类…...

Compose常用UI组件

Compose常用UI组件 概述Modifier 修饰符常用Modifier修饰符作用域限定Modifier Modifier 实现原理Modifier.Element链的构建链的解析 常用基础组件常用布局组件列表组件 概述 Compose 预置了很多基础组件&#xff0c;如 Button&#xff0c;TextField&#xff0c;TopAppBar等&a…...

斐波那契数列模型:在动态规划的丝绸之路上追寻斐波那契的足迹(上)

文章目录 引言递归与动态规划的对比递归解法的初探动态规划的优雅与高效自顶向下的记忆化搜索自底向上的迭代法 性能分析与比较小结 引言 斐波那契数列&#xff0c;这一数列如同一条无形的丝线&#xff0c;穿越千年时光&#xff0c;悄然延续其魅力。其定义简单而优美&#xff…...

Hackthebox- Season7- Titanic 简记 [Easy]

简记 ip重定向到 http://titanic.htb,先添加hosts 收集子域名 wfuzz -c -u http://titanic.htb/ -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -H Host:FUZZ.titanic.htb --hl 9 ******************************************************** * Wfu…...

Sa-Token 根据官方文档简单实现登录认证的示例

Sa-Token 根据官方文档实现登录鉴权测试 功能实现步骤依赖配置文件启动类创建 controller启动项目测试不用密码登录查看cookie状态 密码登录查看cookie状态 修改token名称 Apipost 测试无 cookie 模式【使用 token】后端将 token 返回到前端修改代码&#xff1a;测试&#xff1…...

rustdesk编译修改名字

最近&#xff0c;我用Rust重写了一个2W行C代码的linux内核模块。在此记录一点经验。我此前没写过内核模块&#xff0c;认识比较疏浅&#xff0c;有错误欢迎指正。 为什么要重写&#xff1f; 这个模块2W行代码量看起来不多&#xff0c;却在线上时常故障&#xff0c;永远改不完。…...

BS5852英国家具防火安全条款主要包括哪几个方面呢?

什么是BS5852检测&#xff1f; BS5852是英国针对家用家具的强制性安全要求&#xff0c;主要测试家具在受到燃烧香烟和火柴等火源时的可燃性。这个标准通常分为四个部分进行测试&#xff0c;但实际应用中主要测试第一部分和第二部分&#xff0c;包括烟头测试和利用乙炔火焰模拟…...

【运维】源码编译安装cmake

背景&#xff1a; 已经在本地源码编译安装gcc/g&#xff0c;现在源码安装cmake 下载源码 下载地址&#xff1a;CMake - Upgrade Your Software Build System 安装步骤&#xff1a; ./bootstrap --prefix/usr/local/cmake make make install 错误处理 1、提示找不到libmpc.…...

检测网络安全漏洞 工具

实验一的名称为信息收集和漏洞扫描 实验环境&#xff1a;VMware下的kali linux2021和Windows7 32&#xff0c;网络设置均为NAT&#xff0c;这样子两台机器就在一个网络下。攻击的机器为kali,被攻击的机器为Windows 7。 理论知识记录&#xff1a; 1.信息收集的步骤 2.ping命令…...

frameworks 之 Activity添加View

frameworks 之 Activity添加View 1 LaunchActivityItem1.1 Activity 创建1.2 PhoneWindow 创建1.3 DecorView 创建 2 ResumeActivityItem 讲解 Activity加载View的时机和流程 涉及到的类如下 frameworks/base/core/java/android/app/Activity.javaframeworks/base/services/cor…...

UWB技术中的两种调制方式:PPM与PAM

Ultra-Wideband (UWB) 技术以其低功耗、宽频谱和高精度定位的特点&#xff0c;广泛应用于物联网&#xff08;IoT&#xff09;、智能家居、资产追踪和无线通信等领域。在UWB中&#xff0c;信号的调制方式对于数据传输的效率和精度起着至关重要的作用。本文将深入探讨UWB中常用的…...

达梦:用户和模式

目录标题 数据库管理系统与用户权限管理**四权分立****用户管理与权限划分****用户管理界面与权限控制****用户创建与管理****实操**1. **默认创建用户与模式**&#xff1a;2. **用户权限和角色分配**&#xff1a;3. **命令行管理用户与角色**&#xff1a;4. 模式也可以创建 **…...

23. AI-大语言模型-DeepSeek

文章目录 前言一、DeepSeek是什么1. 简介2. 产品版本3. 特征4. 地址链接5. 三种访问方式1. 网页端和APP2. DeepSeek API 二、DeepSeek可以做什么1. 应用场景2. 文本生成1. 文本创作2. 摘要与改写3. 结构化生成 3. 自然语言理解与分析1. 语义分析2. 文本分类3. 知识推理 4. 编程…...

Spring-GPT智谱清言AI项目(附源码)

一、项目介绍 本项目是Spring AI第三方调用整合智谱请言&#xff08;官网是&#xff1a;https://open.bigmodel.cn&#xff09;的案例&#xff0c;回答响应流式输出显示&#xff0c;这里使用的是免费模型&#xff0c;需要其他模型可以去 https://www.bigmodel.cn/pricing 切换…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...