Acwing1134

算法讲解:短路求方案数问题

问题描述

给定一个无向图,求从起点 1 1 1 到每个节点的最短路径的方案数(即有多少条不同的路径可以到达该节点,且路径长度是最短的)。

关键点
  1. 拓扑性

    • 只有 BFSDijkstra 算法天然具备拓扑性(每次扩展节点时,路径一定是当前最短的)。
    • SPFA 不具备这种特性,因为队列中可能会重复处理某些节点,打破路径的拓扑顺序,导致结果错误。
  2. 核心思想

    • 在判断 dist[j] = dist[t] + w[i] 时,累计当前方案数。
    • 如果发现另一条到达同样距离的路径,继续累加方案数。

代码解析

1. 数据结构定义
const int N = 100010, M = 400010, mod = 100003;int n, m;
int h[N], e[M], ne[M], idx; // 邻接表存储图
int dist[N], cnt[N]; // 最短路径距离 & 方案数
  • 邻接表
    • h[u]:节点 u u u 的第一条边的索引。
    • e[idx]ne[idx]:链式前向星存储目标节点和下一条边的索引。
  • 路径属性
    • dist[u]:从起点 1 1 1 到节点 u u u 的最短路径长度。
    • cnt[u]:从起点 1 1 1 到节点 u u u 的最短路径方案数。

2. 添加边
void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
  • 使用链式前向星添加边。
  • 因为是无向图,每次输入需要调用两次 add,构建双向边。

3. BFS 算法
void bfs() {queue<int> q;q.push(1); // 从起点开始搜索memset(dist, 0x3f, sizeof dist); // 初始化所有点的距离为无穷大dist[1] = 0; // 起点的最短路径为 0cnt[1] = 1; // 起点的方案数为 1while (q.size()) {int t = q.front(); // 当前节点q.pop();for (int i = h[t]; ~i; i = ne[i]) { // 遍历当前节点的所有邻边int j = e[i]; // 目标节点if (dist[j] > dist[t] + 1) { // 找到更短路径dist[j] = dist[t] + 1; // 更新距离cnt[j] = cnt[t]; // 继承当前方案数q.push(j); // 入队} else if (dist[j] == dist[t] + 1) { // 找到同样短的路径cnt[j] = (cnt[j] + cnt[t]) % mod; // 累加方案数并取模}}}
}
关键点解析
  1. 初始化

    • 起点的 dist[1] = 0cnt[1] = 1,表示从起点到起点只有一种方案。
    • 其他节点的 dist 初始化为无穷大,cnt 初始化为 0。
  2. 松弛操作

    • 如果发现更短路径 dist[j] > dist[t] + 1
      • 更新目标节点的最短距离。
      • 当前节点的方案数继承给目标节点。
    • 如果发现同样短的路径 dist[j] == dist[t] + 1
      • 累加当前节点的方案数。
  3. 拓扑性

    • BFS 确保了路径的拓扑顺序,先处理距离较短的节点。
    • 因此,每次更新 cnt[j] 时,已经保证了当前路径是最短路径。

4. 主函数
int main() {cin >> n >> m;memset(h, -1, sizeof h); // 初始化邻接表while (m--) {int a, b;cin >> a >> b;add(a, b), add(b, a); // 添加双向边}bfs();for (int i = 1; i <= n; i++) cout << cnt[i] << endl; // 输出每个点的方案数return 0;
}
  1. 输入图

    • 使用邻接表存储无向图。
    • 每条边调用两次 add,分别加入两个方向。
  2. 调用 BFS

    • 计算从起点到每个节点的最短路径长度和方案数。
  3. 输出

    • 输出每个节点的方案数。

完整流程

  1. 图的构建
    • 使用邻接表存储无向图。
  2. BFS 遍历
    • 初始化起点的 distcnt
    • 使用 BFS 依次处理每个节点,更新邻接节点的最短路径和方案数。
  3. 输出方案数
    • 遍历所有节点,输出到达该节点的方案数。

示例

输入:
4 4
1 2
2 3
3 4
1 3
输出:
1
2
2
2
解释:
  • 从节点 1 1 1 到节点 3 3 3 有两条最短路径: 1 → 3 1 \to 3 13 1 → 2 → 3 1 \to 2 \to 3 123
  • 从节点 1 1 1 到节点 4 4 4 有两条最短路径: 1 → 3 → 4 1 \to 3 \to 4 134 1 → 2 → 3 → 4 1 \to 2 \to 3 \to 4 1234

时间复杂度

  • 邻接表构建 O ( m ) O(m) O(m)
  • BFS 遍历:每条边最多被访问一次,时间复杂度 O ( m ) O(m) O(m)
  • 总复杂度 O ( m + n ) O(m + n) O(m+n)

空间复杂度

  • 邻接表存储边: O ( m ) O(m) O(m)
  • 距离和方案数组: O ( n ) O(n) O(n)

优点与局限性

  1. 优点

    • BFS 自然适用于无权图,确保路径拓扑顺序。
    • 使用 cnt 数组可以高效统计路径方案数。
    • 通过 mod 防止数值溢出。
  2. 局限性

    • 仅适用于无权图或边权恒为 1 的场景。
    • 对于有权图,需要使用 Dijkstra 替代 BFS。

这段代码利用 BFS 的拓扑性,巧妙地解决了无权图中的最短路径方案数问题,并且结构清晰,易于扩展!

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

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

相关文章

Linux性能优化之火焰图的起源

Linux火焰图的起源与性能优化专家 Brendan Gregg 密切相关&#xff0c;他在 2011 年首次提出这一工具&#xff0c;用于解决性能分析过程中可视化和数据解读的难题。 1. 背景&#xff1a;性能优化的需求 在现代计算中&#xff0c;性能优化往往需要对程序执行中的热点和瓶颈进行…

半桥驱动芯片调试中的问题

结论&#xff1a;低于12V的场景应用分立的MOS驱动电路压根不合适&#xff0c;选用集成桥臂的芯片合适。 HIN的输入电平不能是长时间的高电平&#xff0c;否则自举电容没法充放电从而没办法自举升压&#xff0c;上管无法控制&#xff1a; 电容C2的容值应该尽可能大&#xff…

【C++】类和对象-深度剖析默认成员函数-上

> &#x1f343; 本系列为初阶C的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:[小编的个人主页])小编的个人主页 > &#x1f380; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 > ✌️ &#x1f91e; &#x1…

RabbitMQ黑马笔记

目录 1.初识MQ 1.1.同步和异步通讯 1.1.1.同步通讯 1.1.2.异步通讯 1.2.技术对比&#xff1a; 2.快速入门 2.1.安装RabbitMQ 2.2.RabbitMQ消息模型 2.3.导入Demo工程 2.4.入门案例 2.4.1.publisher实现 2.4.2.consumer实现 2.5.总结 3.SpringAMQP 3.1.Basic Queu…

麒麟KylinServer的网站,并部署一套主从DNS服务器提供域名解析服务

一、KylinServer网站搭建 ifconfig Copy 注意:根据实际网卡设备名称情况调整代码!不同环境下网卡名称略有不同! 获取本机IP地址,记住IP地址用于之后的配置填写。 ifconfig enp0s2 Copy 下载nginx源码包,并解压缩 wget http://10.44.16.102:60000/allfiles/Kylin/ng…

解决IntelliJ IDEA的Plugins无法访问Marketplace去下载插件

勾选Auto-detect proxy setting并填入 https://plugins.jetbrains.com 代理URL&#xff0c;可以先做检查连接&#xff1a;

AWTK-WIDGET-WEB-VIEW 发布

awtk-widget-web-view 是通过 webview 提供的接口&#xff0c;实现的 AWTK 自定义控件&#xff0c;使得 AWTK 可以方便的显示 web 页面。 项目网址&#xff1a; https://gitee.com/zlgopen/awtk-widget-web-view webview 提供了一个跨平台的 webview 接口&#xff0c;是一个非…

Pandas教程之Pandas 简介

Pandas 简介 接下来一段时间&#xff0c;我会持续发布并完成Pandas教程 Pandas 是一个功能强大的开源 Python 库。Pandas 库用于数据操作和分析。Pandas 由数据结构和函数组成&#xff0c;可对数据执行有效的操作。 本免费教程将概述 Pandas&#xff0c;涵盖 Python Pandas 的基…

【linux】网络基础 ---- 数据链路层

用于两个设备(同一种数据链路节点)之间进行传递 数据链路层解决的问题是&#xff1a;直接相连的主机之间&#xff0c;进行数据交付 1. 认识以太网 "以太网" 不是一种具体的网络, 而是一种技术标准&#xff1a; 既包含了数据链路层的内容, 也包含了一些物理层的内容…

i春秋-FUZZ(python模板注入、base64编码命令执行)

练习平台地址 竞赛中心 题目描述 题目内容 很直接就是要fuzz参数 参数字典 dpaste/eH2Z1 (Plain Text) BP爆破参数 发现存在name参数 尝试sql注入 发现输入啥就回显啥&#xff0c;猜测是模板注入 测试是不是模板注入 虽然9*9没有被执行&#xff0c;但是config执行了&#…

另外一种缓冲式图片组件的用法

文章目录 1. 概念介绍2. 使用方法2.1 基本用法2.2 缓冲原理3. 示例代码4. 内容总结我们在上一章回中介绍了"FadeInImage组件"相关的内容,本章回中将介绍CachedNetworkImage组件.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章回中介绍的CachedNetwo…

Java中的CAS

目录 一.问题提出 1.1解决思路-锁 1.2解决思路-无锁 二.什么是CAS 三.CAS的特点 四.ABA问题 4.1解决方案-AtomicStampedReference 4.2解决方案-AtomicMarkableReference 一.问题提出 如何保证 withdraw 取款方法的线程安全 public class Cas {public static void mai…

git push时报错! [rejected] master -> master (fetch first)error: ...

错误描述&#xff1a;在我向远程仓库push代码时&#xff0c;即执行 git push origin master命令时发生的错误。直接上错误截图。 错误截图 错误原因&#xff1a; 在网上查了许多资料&#xff0c;是因为Git仓库中已经有一部分代码&#xff0c;它不允许你直接把你的代码覆盖上去…

药房智控:中药实验管理的自动化

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

C语言实现数据结构之二叉树

文章目录 二叉树一. 树概念及结构1. 树的概念2. 树的相关概念3. 树的表示4. 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 二. 二叉树概念及结构1. 概念2. 特殊的二叉树3. 二叉树的性质4. 二叉树的存储结构 三.二叉树链式结构的实现1. 前置说明2. 二叉树…

SpringCloud篇(服务保护 - Sentinel)

目录 一、雪崩问题及解决方案 1. 雪崩问题 2. 解决方案 方案一&#xff1a;超时处理 方案二&#xff1a;仓壁模式 方案三&#xff1a;断路器模式 方案四&#xff1a;限流 3. 总结 二、服务保护技术对比 三、Sentinel介绍与安装 1. 初识Sentinel 2. Sentinel 优势 3…

MCU的时钟体系

stm32F4的时钟体系图 1MHZ 10^6 HZ 系统时钟频率是168MHZ;AHB1、AHB2、AHB3总线上的时钟频率是168MHz;APB1总线上的时钟频率为42MHz&#xff1b;APB2总线上的时钟频率为84MHz&#xff1b; stm32F4的时钟体系图 在system_stm32f4xx.c文件中查看APB1和APB2的预分频值到底是多少…

Redis设计与实现 学习笔记 第十八章 发布与订阅

第18到24章是本书第四部分&#xff1a;独立功能的实现。 Redis的发布与订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成。 通过执行SUBSCRIBE命令&#xff0c;客户端可订阅一个或多个频道&#xff0c;从而成为这些频道的订阅者&#xff08;subscriber&#xff09;&#…

小程序-基于java+SpringBoot+Vue的驾校预约平台设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

python多版本管理 windows11 pyenv

前言 需要开发多个项目&#xff0c;但各个项目的版本不一致怎么办&#xff1f;python -m venv 只解决了依赖隔离问题&#xff0c;但venv本身并没有办法提供多个python版本。因此我们要引入pyenv来解决。 安装pyenv https://pyenv-win.github.io/pyenv-win/ 安装很简单&…