每周一算法:最短路计数

题目描述

给出一个 N N N个顶点 M M M 条边的无向无权图,顶点编号为 1 1 1 N N N

问从顶点 1 1 1 开始,到其他每个点的最短路有几条。

输入格式

第一行包含 2 2 2 个正整数 N , M N,M N,M,为图的顶点数与边数。

接下来 M M M 行,每行两个正整数 x , y x,y x,y,表示有一条顶点 x x x 连向顶点 y y y 的边,请注意可能有自环与重边。

输出格式

输出 N N N 行,每行一个非负整数,第 i i i 行输出从顶点 1 1 1 到顶点 i i i 有多少条不同的最短路,由于答案有可能会很大,你只需要输出对 100003 100003 100003 取模后的结果即可。

如果无法到达顶点 i i i 则输出 0 0 0

样例 #1

样例输入 #1

5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5

样例输出 #1

1
1
1
2
4

提示

【数据范围】
1 ≤ N ≤ 1 0 5 1≤N≤10^5 1N105,
1 ≤ M ≤ 2 × 1 0 5 1≤M≤2×10^5 1M2×105

算法思想

根据题目描述,求从起点 1 1 1 到每个顶点有多少条不同的最短路,即求最短路的方案数。可以使用动态规划的思想,定义状态 f [ i ] f[i] f[i]表示起点到顶点 i i i的最短路的方案数。

要在图中计算状态,需要先构造出图的拓扑序列。但是题目中给出的是无向无权图,通过测试样例可以看出,图中有可能存在环,如下图所示,因此不一定存在拓扑序列,因此不能通过循环迭代直接计算状态。
在这里插入图片描述
由于求的是最短路的方案数,考虑能否使用最短路算法,在计算最短路的同时将状态计算出来。要使用最短路计算方案数需要要满足不能存在代价为 0 0 0的环,否则经过该环的最短路的方案数为无穷大。而题目中题目给出的是无向无权图,可以认为边权都为 1 1 1,因此不存在代价为 0 0 0的环。

那么有哪些最短路算法可以进行状态计算呢?

题目求的是起点到其余顶点的最短路,那么可以选择的最短路算法有:BFS、Dijkstra、Bellman-Ford(SPFA)等,是不是这些算法都可以用来计算状态呢?要计算 i i i点的状态,必须保证 i i i阶段所依赖的状态都已经被计算出来,也就是说在计算最短路时,能够找到一个拓扑序来计算状态。这样就需要最短路算法能够构造出一个最短路拓扑图。如下图所示:
在这里插入图片描述

而对于下列算法:

  • BFS算法计算(边权相同的)最短路时,是一层一层进行扩展的,每个点只会入队 1 1 1次,出队 1 1 1次,进队和出队都是满足拓扑序的。
  • Dijkstra算法计算最短路时,每个点只会出队 1 1 1次,当一个点出队时,是不会更新前面已经出队的点到起点的最短路,因此出队序列也满足拓扑序。
  • Bellman-Ford(SPFA)算法计算最短路时,每个点可以入队出队多次,当一个点出队时可能会更新之前出队的点的最短路,这样就不能保证出队序列具备拓扑序。

也就是说, BFS和 Dijkstra算法在求最短路过程中可以进行状态计算。

算法流程

  • 将起点 1 1 1的最短路径方案数初始化为 1 1 1,即 f [ 1 ] = 1 f[1] = 1 f[1]=1
  • 在求解最短路的过程中
    • v v v点到起点的最短路能够被 u u u点松弛,即 d i s [ v ] > d i s [ u ] + 1 dis[v] > dis[u] + 1 dis[v]>dis[u]+1,则到 v v v的最短路方案数等于到 u u u点的最短路方案数,即 f [ v ] = f [ u ] f[v] = f[u] f[v]=f[u]
    • v v v点到起点的最短路等于经过 u u u点中转的距离,则需要累加到 u u u点的最短路方案数,即 f [ v ] = f [ v ] + f [ u ] f[v] =f[v] + f[u] f[v]=f[v]+f[u]

代码实现

#include <bits/stdc++.h>
//注意:边数为200000,无向图需要建双向边,所以边的总数为400010
const int N = 100010, M = 400010, mod = 100003;
int n, m;
int h[N], e[M], ne[M], idx;
//dist[i]表示从1号点到i号点的最短距离
//f[i]表示从1到点到i号点的最短距离的路径数
int dis[N], f[N], q[N];
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void bfs()
{
    memset(dis, 0x3f, sizeof dis);
    //注意,到1号点的最短路径数初始为1
    dis[1] = 0, f[1] = 1;
    //bfs每个点只会入队一次,使用普通队列即可
    int hh = 0, tt = 0;
    q[0] = 1;
    while(hh <= tt)
    {
        int u = q[hh ++];
        for(int i = h[u]; ~i; i = ne[i])
        {
            int v = e[i];
            //可以更新最短距离
            if(dis[v] > dis[u] + 1)
            {
                dis[v] = dis[u] + 1;
                q[++ tt] = v;
                //此时的路径数不变
                f[v] = f[u];
            }   
            else if(dis[v] == dis[u] + 1)//如果最短距离相等,累加最短路径数
            {
                f[v] = (f[v] + f[u]) % mod;
            }
        }
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);
    while(m --)
    {
        int a, b;
        scanf("%d%d", &a, &b);
       
        add(a, b), add(b, a);  //无向图,双向边
    }
    bfs();
    for(int i = 1; i <= n; i++) printf("%d\n", f[i]);
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux基础命令[25]-groupadd

文章目录 1. groupadd 命令说明2. groupadd 命令语法3. groupadd 命令示例3.1 不加参数3.2 -f&#xff08;强制创建&#xff09;3.3 -g&#xff08;指定组ID&#xff09;3.4 -r&#xff08;系统用户组&#xff09; 4. 总结 1. groupadd 命令说明 groupadd&#xff1a;用于创建…

C语言入门课程学习记录4

C语言入门课程学习记录4 第18课 - signed 与 unsigned第19课 - 再论数据类型第20课 - 经典问题剖析第21课 - 程序中的辅助语句&#xff08;上&#xff09;第22课 - 程序中的辅助语句&#xff08;下&#xff09; 本文学习自狄泰软件学院 唐佐林老师的 C语言入门课程&#xff0c;…

【C++】:拷贝构造函数和赋值运算符重载

目录 一&#xff0c;拷贝构造函数1. 什么是拷贝构造函数2. 拷贝构造函数的特性3. 实践总结 二&#xff0c;赋值运算符重载2.1 运算符重载2.2 赋值运算符重载 一&#xff0c;拷贝构造函数 1. 什么是拷贝构造函数 拷贝构造函数是特殊的构造函数。是用一个已经存在的对象&#x…

JVM虚拟机监控及性能调优实战

目录 jvisualvm介绍 1. jvisualvm是JDK自带的可以远程监控内存&#xff0c;跟踪垃圾回收&#xff0c;执行时内存&#xff0c;CPU/线程分析&#xff0c;生成堆快照等的工具。 2. jvisualvm是从JDK1.6开始被继承到JDK中的。jvisualvm使用 jvisualvm监控远程服务器 开启远程监控…

软考高级 | 系统架构设计师笔记(一)

一. 系统规划 1.1 项目的提出与选择 该步骤生成” 产品/项目建议书”. 1.2 可行性研究与效益分析 包括经济可行性/技术可行性/法律可行性/执行可行性/方案选择 5 个部分. 该步骤生 成”可行性研究报告”. 1.3 方案的制订和改进 包括确定软件架构/确定关键性要素?/确定计算…

java Web-Spring AOP

AOP的概念 AOP:面向切面编程&#xff0c;面向方法编程。简单理解就是对特定方法的扩充的思想 例如我们要在特定方法进行方法的执行时间判断&#xff0c;我们假如去使用在每个方法去进行业务逻辑扩充&#xff0c;这样就太繁琐了&#xff0c;而使用AOP就可以简化操作。Spring A…

mybatis中<if>条件判断带数字的字符串失效问题

文章目录 一、项目背景二、真实错误原因说明三、解决方案3.1针对纯数字的字符串值场景3.2针对单个字符的字符串值场景 四、参考文献 一、项目背景 MySQL数据库使用Mybatis查询拼接select语句中进行<if>条件拼接的时候&#xff0c;发现带数字的或者带单个字母的字符串失效…

vue基础教程(7)——构建项目级首页

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、页面结构二、侧边栏三、主体部分总结 前言 前面我们学习了vue的路由和登录页搭建&#xff0c;本文将和大家共同学习首页的搭建。 首页示例如图&#xff1a; 很多项目经验比较少的同学&#xff0c;一般都是对某些语…

架构师系列-消息中间件(八)- RocketMQ 进阶(二)-生产端消息保障

5. RocketMQ消息保障 下面我们详细说下如何保障消息不丢失以及消息幂等性问题 5.1 生产端保障 生产端保障需要从一下几个方面来保障 使用可靠的消息发送方式注意生产端重试生产禁止自动创建topic 5.1.1 消息发送保障 5.1.1.1 同步发送 发送者向MQ执行发送消息API时&#xff0…

springBoot集成flowable

前言 Flowable可以十分灵活地加入你的应用/服务/构架。可以将JAR形式发布的Flowable库加入应用或服务&#xff0c;来嵌入引擎。 以JAR形式发布使Flowable可以轻易加入任何Java环境&#xff1a;Java SE&#xff1b;Tomcat、Jetty或Spring之类的servlet容器&#xff1b; JBoss…

网工内推 | 上市公司网络运维,大专可投,NA/NP认证优先

01 珠海世纪鼎利科技股份有限公司 招聘岗位&#xff1a;网络运维工程师 职责描述&#xff1a; 1、负责服务器安装、维护和设备管理&#xff1b; 2、负责应用系统的部署&#xff0c;升级&#xff0c;维护&#xff1b; 3、分析网络数据&#xff0c;排查网络故障及事务的应急响应…

百度网盘svip白嫖永久手机2024最新教程

百度网盘&#xff08;原名百度云&#xff09;是百度推出的一项云存储服务&#xff0c;已覆盖主流PC和手机操作系统&#xff0c;包含Web版、Windows版、Mac版、Android版、iPhone版和Windows Phone版。用户将可以轻松将自己的文件上传到网盘上&#xff0c;并可跨终端随时随地查看…

【C语言】红黑树详解以及C语言模拟

一、红黑树的性质二、红黑树的旋转操作三、红黑树的插入操作四、红黑树的删除操作五、红黑树的应用六、C语言模拟红黑树七、总结 红黑树是一种自平衡二叉查找树&#xff0c;它能够保持树的平衡&#xff0c;从而确保查找、插入和删除的最坏情况时间复杂度为O( l o g n log_n log…

软考-系统集成项目管理中级--项目人力资源管理(输入输出很重要!!!本章可能包含案例题)

本章历年考题分值统计 本章重点常考知识点汇总清单(学握部分可直接理解记忆) 10、项目沟通管理计划一般应包括以下内容:(掌握)12上59&#xff0c;10下59&#xff0c;13上53&#xff0c;13上57,14下58&#xff0c;15下58&#xff0c;16上59 考题 (1)干系人的沟通需求。 (2)针对沟…

爬虫抓取网站数据

Fiddler 配置fiddler工具结合浏览器插件 配置fiddler Tools--Options 抓包技巧 谷歌浏览器开启无痕浏览,使用SwitchyOmega配置好代理端口 Ctrl x 清理所有请求记录,可以删除指定不需要日志方便观察 设置按请求顺序 观察cookie,观察请求hesder cookie和row返回结果 Swit…

C++/QT + Mysql + Tcp 企业协作管理系统

目录 一、项目介绍 二、项目展示 三、源码获取 一、项目介绍 1、项目概要&#xff1a;C/S架构、数据库Mysql、C、QT&#xff1b;支持实时通信、局域网内通信&#xff0c;可多个客户端同时登录&#xff1b; 2、&#xff08;Server&#xff09;管理端&#xff1a;用户管理、…

科技云报道:AIGC掀算力需求革命,边缘计算将不再“边缘”

科技云报道原创。 随着以大模型为代表的AIGC时代拉开序幕&#xff0c;算力需求持续爆发&#xff0c;AI与边缘深度融合已是大势所趋&#xff0c;越来越多的企业开始积极布局GenAI。 GenAI技术的商用化部署和应用成为企业竞逐的新阵地&#xff0c;勾勒出大模型从“技术力”转向…

数组模拟几种基本的数据结构

文章目录 数组模拟单链表数组模拟双链表数组实现栈数组模拟队列总结 数组模拟单链表 首先类比结构体存储单链表&#xff0c;我们需要一个存放下一个节点下标的数组&#xff0c;还需要一个存储当前节点的值的数组&#xff0c;其次就是一个int类型的索引&#xff0c;这个索引指向…

挑战一周完成Vue3实战项目硅谷甄选Day1:项目初始化、项目配置、项目集成

一、项目初始化 node v16.4.0以上&#xff08;查看node版本 : node -v&#xff09; pnpm 8.0.0&#xff08;npm i -g pnpm8.0.0&#xff09; 在想创建的位置新建文件夹自己命名 在此文件夹下cmd:pnpm create vite 选择如下配置 Project name&#xff08;项目名称&#xff0…
最新文章