📜  门| GATE-CS-2016(套装1)|问题 5(1)

📅  最后修改于: 2023-12-03 14:58:31.299000             🧑  作者: Mango

门| GATE-CS-2016(套装1)|问题 5
介绍

本题是关于图的遍历和连通性的问题,能够深入理解深度优先搜索(DFS)和广度优先搜索(BFS)的实现方法。

题目要求实现一个函数 find_shortest_distance(n: int, edges: List[Tuple[int, int]], u: int, v: int) -> int,其中 n 是节点数量,edges 是一个列表,存储所有边的起点和终点坐标,uv 是给定的两个节点编号,函数返回 uv 的最短距离。

解题思路

本题可以采用 BFS 来实现,从起点 u 出发,遍历与它相连通的所有节点,找到与终点 v 相连通的最短路径。

BFS 遍历过程中,每个节点都要记录它距离起点的步数,也就是到达该节点的路径长度。将起点的步数初始化为 0,其他节点的步数默认为无限大,遍历相邻节点时,如果发现新相邻节点的步数比之前记录的小,那么就更新该相邻节点的步数,并以该节点为起点继续遍历。

在遍历过程中,还需要记录已访问的节点,避免重复访问。

解题方法
  1. 构建一个空的邻接表,使用 Python 的字典类型作为邻接表。邻接表的结构如下:
adj_list = {0: [1, 2], 1: [0, 2], 2: [0, 1]}

其中的键值对表示节点编号和相邻节点的列表。

  1. 构造一个节点步数的列表,使用 Python 的列表类型记录每个节点的步数。步数列表的结构如下:
dist = [float('inf')] * n

其中的列表长度为节点数 n,所有节点的步数默认初始化为无限大。

  1. 采用 BFS 遍历方式搜索最短路径。实现代码如下:
def bfs(start, end):
    visited.append(start)
    dist[start] = 0
    q = deque([])
    q.append(start)
    while q:
        curr = q.popleft()
        for next in adj_list[curr]:
            if next not in visited:
                visited.append(next)
                dist[next] = dist[curr] + 1
                q.append(next)
                if next == end:
                    return dist[next]
    return -1

其中 start 为起点编号,end 为终点编号,visited 列表存储已经访问的节点,dist 列表存储起点到每个节点的步数。

  1. 最后返回搜索结果,如果没有找到符合条件的路径,则返回 -1。函数实现代码如下:
from collections import deque
from typing import List, Tuple

def find_shortest_distance(n: int, edges: List[Tuple[int, int]], u: int, v: int) -> int:
    # build adjacency list
    adj_list = {}
    for i in range(n):
        adj_list[i] = []
    for edge in edges:
        adj_list[edge[0]].append(edge[1])
        adj_list[edge[1]].append(edge[0])

    # initialize variables
    visited = []
    dist = [float('inf')] * n
    
    # search for shortest path using BFS
    return bfs(u, v)
复杂度分析

本算法的时间复杂度为 O(n+m),其中 n 为节点数,m 为边数。在最坏情况下,需要遍历所有节点和边才能找到最短路径,因此时间复杂度最大为 O(n+m)。空间复杂度为 O(n+m),需要存储邻接表、节点步数、visited 列表和队列数据结构。