判断图上两点是否可达

199 阅读3分钟

判断图上两点是否可达是图论中的一个经典问题,可以通过多种算法来解决。常见的方法包括深度优先搜索(DFS)、广度优先搜索(BFS)和最短路径算法(如Dijkstra算法)。下面分别介绍这三种方法及其实现。

1. 深度优先搜索(DFS)

思想:从起点出发,递归地探索所有可能的路径,直到找到终点或所有路径都已探索完毕。

步骤

  1. 初始化一个布尔数组 visited,用于记录每个节点是否被访问过。
  2. 从起点开始进行DFS遍历。
  3. 如果在遍历过程中到达终点,则说明两点可达。
  4. 如果遍历结束仍未到达终点,则说明两点不可达。

代码实现(Python):

def dfs(graph, start, end, visited):
    if start == end:
        return True
    visited[start] = True
    for neighbor in graph[start]:
        if not visited[neighbor]:
            if dfs(graph, neighbor, end, visited):
                return True
    return False

def is_reachable_dfs(graph, start, end):
    visited = [False] * len(graph)
    return dfs(graph, start, end, visited)

2. 广度优先搜索(BFS)

思想:从起点出发,逐层扩展,直到找到终点或所有路径都已扩展完毕。

步骤

  1. 初始化一个队列 queue,将起点加入队列。
  2. 初始化一个布尔数组 visited,用于记录每个节点是否被访问过。
  3. 从队列中取出一个节点,标记为已访问。
  4. 将该节点的所有未访问邻居加入队列。
  5. 重复步骤3和4,直到队列为空。
  6. 如果在遍历过程中到达终点,则说明两点可达。
  7. 如果遍历结束仍未到达终点,则说明两点不可达。

代码实现(Python):

from collections import deque

def is_reachable_bfs(graph, start, end):
    visited = [False] * len(graph)
    queue = deque([start])
    visited[start] = True
    
    while queue:
        current = queue.popleft()
        if current == end:
            return True
        for neighbor in graph[current]:
            if not visited[neighbor]:
                visited[neighbor] = True
                queue.append(neighbor)
    
    return False

3. 最短路径算法(Dijkstra算法)

思想:计算从起点到终点的最短路径,如果存在最短路径,则说明两点可达。

步骤

  1. 初始化一个距离数组 dist,记录从起点到每个节点的最短距离。
  2. 初始化一个优先队列 pq,将起点的距离设为0并加入队列。
  3. 从优先队列中取出距离最小的节点,更新其邻居节点的距离。
  4. 重复步骤3,直到优先队列为空。
  5. 如果终点的距离不是无穷大,则说明两点可达。

代码实现(Python):

import heapq

def dijkstra(graph, start, end):
    n = len(graph)
    dist = [float('inf')] * n
    dist[start] = 0
    pq = [(0, start)]
    
    while pq:
        current_dist, current = heapq.heappop(pq)
        
        if current == end:
            return True
        
        if current_dist > dist[current]:
            continue
        
        for neighbor, weight in graph[current]:
            distance = current_dist + weight
            if distance < dist[neighbor]:
                dist[neighbor] = distance
                heapq.heappush(pq, (distance, neighbor))
    
    return dist[end] != float('inf')

def is_reachable_dijkstra(graph, start, end):
    return dijkstra(graph, start, end)

总结

  • DFS:适用于无权图或有权图,递归实现,适合较小的图。
  • BFS:适用于无权图,非递归实现,适合较大的图。
  • Dijkstra:适用于有权图,计算最短路径,适合需要最短路径信息的场景。