数据结构与算法-图论-最短路-拓展运用

选择最佳路线

分析:

这是一道图论中的最短路径问题,目标是在给定的公交网络中,找到从琪琪家附近的车站出发,到她朋友家附近车站(编号为 s )的最短时间。以下是对该问题的详细分析:

问题关键信息

图的结构:

图由 n 个车站(节点)和 m 条公交线路(有向边)组成,边是单向的,且两节点间可能有多条边。

每条边(公交线路)有起点 p、终点 q 和花费时间 t 的属性。

起始点和终点:

终点是朋友家附近的车站,编号为 s 。

起始点可以从琪琪家附近的 w 个车站中任选一个。

求解目标:计算从可选择的起始点到终点的最短时间。

解题思路

建图:使用邻接表或邻接矩阵来存储图的信息。对于每条公交线路(p, q, t),在图中添加从节点 p 到节点 q 、权重为 t 的有向边。

最短路径算法:可以使用 Dijkstra 算法(适用于没有负权边的情况,本题中时间不会为负)或 Bellman - Ford 算法(可以处理负权边,但本题不需要)。从琪琪家附近的每个车站(起始点)开始,计算到其他所有车站的最短距离。(使用虚拟节点)

结果处理:在计算出从每个起始点到所有车站的最短距离后,找到到达编号为 s 的车站的最短时间。

伪代码:

拯救大兵瑞恩:

分析:

这是一道基于图论和搜索算法的迷宫路径求解问题,核心在于在带有门和钥匙限制的迷宫中,找到从起点到终点的最短路径。以下是对该问题的详细分析:

问题关键信息

  • 迷宫结构: - 迷宫是一个 N times M 的长方形区域,由 N 行和 M 列的单元组成,每个单元位置用有序数对(行号,列号)表示。

  • 相邻单元间可能互通、有锁着的门或不可逾越的墙,门是无向的,可双向通过。 - 钥匙与门: - 迷宫中部分单元存放钥匙,同一单元可能有多把钥匙。

  • 门分为 P 类,打开同一类门的钥匙相同,不同类门钥匙不同。

  • 起点与终点:

  • 起点为迷宫西北角的 (1, 1) 单元,麦克可直接进入。

  • 终点是迷宫东南角的 (N, M) 单元,大兵瑞恩昏迷于此。

  • 移动时间:麦克从一个单元移动到相邻单元的时间为 1,拿钥匙和开门时间忽略不计。 - 求解目标:设计算法找到麦克从起点到终点的最快(最短时间)路径。

解题思路

  1. 状态表示:除了记录位置坐标 (x, y) 外,还需记录当前拥有的钥匙状态。可以用一个二进制数或集合来表示拥有哪些类别的钥匙,假设钥匙类别从 0 到 P - 1 编号,二进制数中第 i 位为 1 表示拥有第 i 类钥匙。这样每个状态可以表示为 (x, y, key_status)

  2. 建图或搜索空间构建:根据迷宫的连通性、门和钥匙的关系,构建搜索空间。对于每个单元,考虑其相邻单元,若相邻单元间是墙则不可达;若是门,需判断是否有对应的钥匙;若是通路则可直接到达。

  3. 搜索算法:使用广度优先搜索(BFS)算法较为合适,因为 BFS 能保证找到的路径是最短的(在单位移动时间的情况下)。从起点 (1, 1, 初始钥匙状态) 开始搜索,将可达的状态加入队列,不断扩展,直到找到终点 (N, M, _) (钥匙状态任意)。

  4. 剪枝优化:为了减少搜索量,可以进行一些剪枝操作。比如记录已经访问过的状态 (x, y, key_status) ,如果再次遇到相同状态则不再重复处理。

伪代码:

最短路计数:

分析:

这是一道图论中的最短路径计数问题,要求计算从顶点1到图中其他每个顶点的最短路径的数量。由于图是无向无权的,所以可以使用广度优先搜索(BFS)算法来解决。以下是详细分析:

问题关键信息

  • 图的属性:

  • 给定一个包含 N 个顶点(编号为 1 到 N)和 M 条边的无向无权图。

  • 图中可能存在自环(顶点自身到自身的边)和重边(两个顶点之间有多条边)。 - 起始顶点和目标:

  • 起始顶点为顶点 1 。

  • 目标是计算从顶点 1 到其他每个顶点的最短路径的数量。

  • 输出要求: - 输出 N 行,每行一个非负整数,表示从顶点 1 到对应顶点的不同最短路径的数量,结果对 100003 取模。 - 如果无法到达某个顶点,则输出 0 。

解题思路

  1. 建图:使用邻接表来存储图的结构,对于每一条边 (x, y),在邻接表中分别在顶点 x 和顶点 y 的邻接表中添加对方。

  2. BFS 搜索:从顶点 1 开始进行 BFS 。在 BFS 的过程中,维护两个数组: - `dist[i]` 表示从顶点 1 到顶点 i 的最短距离,初始化为无穷大,顶点 1 的距离初始化为 0 。 - `count[i]` 表示从顶点 1 到顶点 i 的最短路径的数量,初始化为 0 ,顶点 1 的数量初始化为 1 。

  3. 状态更新:在 BFS 遍历过程中,对于当前顶点 u 的每个邻接顶点 v : - 如果 `dist[v]` 为无穷大,说明这是第一次访问到顶点 v,则 `dist[v] = dist[u] + 1`,`count[v] = count[u]` 。 - 如果 `dist[v] = dist[u] + 1`,说明找到了一条新的最短路径,那么 `count[v] = (count[v] + count[u]) % 100003` 。

  4. 输出结果:遍历顶点 1 到顶点 N,输出 `count[i]` ,如果 `dist[i]` 仍然是无穷大,说明无法到达顶点 i,则输出 0 。

伪代码:

观光

分析:

这是一道图论中的路径计数问题,要求在给定的公交路线图中,找出从起始城市 S 到目标城市 F 的满足特定距离条件(最短路径或比最短路径多一个单位长度)的路径数量。下面是详细分析:

问题关键信息

  • 图的属性
    • 公交路线图可看作一个图,城市为顶点,公交路线为边,边有权重(代表路程长度)。
    • 图中可能存在重边和不同的路径组合。
  • 起始和目标
    • 起始城市为 S,目标城市为 F。
  • 路径条件
    • 旅客可选的路径需满足:要么是 S 到 F 的最短路径,要么总路程仅比最短路径多一个单位长度。
  • 求解目标
    • 计算满足上述条件的不同路径的数量。

解题思路

  1. 计算最短路径 :使用 Dijkstra 算法或 Bellman - Ford 算法(本题边权非负,Dijkstra 更高效)来计算从城市 S 到其他所有城市的最短距离,记为 dist[i],其中 i 表示城市编号,这样能得到 S 到 F 的最短距离 min_dist。
  2. 路径搜索与计数 :使用深度优先搜索(DFS)或广度优先搜索(BFS)遍历图,在搜索过程中记录路径长度。
    • 当路径长度等于 min_dist 时,路径计数加 1。
    • 当路径长度等于 min_dist + 1 时,路径计数也加 1。
    • 为避免重复计数,可使用一个标记数组记录已经访问过的城市状态(对于每个城市记录当前路径长度下是否已访问)。
  3. 输出结果 :将满足条件的路径数量输出。

伪代码:

相关推荐
银河梦想家7 小时前
【Day48 LeetCode】图论问题 Ⅵ
算法·leetcode·图论
银河梦想家7 小时前
【Day47 LeetCode】图论问题 Ⅴ
算法·leetcode·图论
闻缺陷则喜何志丹7 小时前
【二分查找 图论】P8794 [蓝桥杯 2022 国 A] 环境治理|普及
c++·算法·蓝桥杯·二分查找·图论·城市·治理
银河梦想家1 天前
【Day46 LeetCode】图论问题 Ⅳ
leetcode·深度优先·图论
Ritsu栗子1 天前
代码随想录算法训练day64---图论系列8《拓扑排序&dijkstra(朴素版)》
c++·算法·图论
Ritsu栗子2 天前
代码随想录算法训练day63---图论系列7《prim算法&kruskal算法》
c++·算法·图论
一只码代码的章鱼2 天前
数据结构与算法-图论-最短路-单源最短路的建图方式
算法·图论
JNU freshman3 天前
图论 之 迪斯科特拉算法求解最短路径
算法·图论
旅僧3 天前
代码随想录-- 第一天图论 --- 岛屿的数量
算法·深度优先·图论