📅  最后修改于: 2023-12-03 14:58:35.566000             🧑  作者: Mango
在一个$n$个点的有向图中,节点被标为$1,2,...,n$。一些节点有门,门用$1$和$0$标记,其中$0$表示门关闭,$1$表示门打开。给定一个起点和一个终点,要求找到从起点到终点的最短路径,经过的节点不能经过门为$0$的节点。若无法到达,则输出$-1$。
考虑用广度优先搜索(BFS)来解决此问题。
首先,可以将有门的节点看作障碍物,用一个二维数组$obstacle$来记录。具体而言,如果节点$i$有门,那么$obstacle_i=1$;否则,$obstacle_i=0$。接下来,用一个$visited$数组来记录到过了哪些节点。对于每个节点$i$,$visited_i=1$表示已经访问过;否则,$visited_i=0$表示未访问过。
接下来进入BFS的主体。使用一个队列$queue$和一个距离数组$distance$来记录当前节点和到起点的距离。队列的初始状态是只有起点,距离为$0$。每次从队列中取出一个节点$i$时,枚举所有它指向(即$i->j$)的节点$j$:
最后,如果终点没有被访问过,那么无法到达;否则,输出$distance_{end}$。
from collections import deque
def bfs(start, end, n, obstacles):
visited = [0] * (n + 1)
distance = [-1] * (n + 1)
queue = deque([(start, 0)])
visited[start] = 1
distance[start] = 0
while queue:
curr, dist = queue.popleft()
for next_node in range(1, n + 1):
if curr == next_node or not obstacles[next_node]:
continue
if not visited[next_node]:
visited[next_node] = 1
distance[next_node] = dist + 1
queue.append((next_node, dist + 1))
if visited[end]:
return distance[end]
return -1