📜  门|门 CS 1997 |第 52 题(1)

📅  最后修改于: 2023-12-03 15:28:47.645000             🧑  作者: Mango

题目描述

已知一个 n*m 的地图,地图中用 1 表示墙,用 0 表示空地,用 2 表示门。门可以打开,打开后门即可与外界相连,门的位置不会发生改变。现在需要你求出从所有门到所有空地的最短距离。其中,从一个点到另一个点的距离定义为从一个点走到另一个点所需的最小步数(上下左右移动一格算一个步数)。

输入格式

第一行包含两个整数n,m,表示地图的大小。

接下来 n 行,每行包含m个整数,表示地图中的元素。

输出格式

输出一个 n*m 的矩阵,表示每个点到门的最短距离,如果某个点无法到达任何一个门,输出 -1。

输入样例

6 6
0 0 0 1 2 0
0 1 0 0 1 0
0 0 0 1 0 1
1 1 1 1 0 0
0 0 0 0 0 1
0 1 1 1 0 0

输出样例

5 4 3 -1 0 1
6 -1 2 3 -1 2
7 6 5 -1 2 -1
-1 -1 -1 -1 3 4
5 4 3 2 1 -1
6 -1 -1 -1 2 3

算法

本题需要求解多源最短路径,可以使用 BFS 算法。

从每个门出发,进行 BFS,更新每个空地的最短路径长度。

可以使用队列来实现 BFS。

代码

def bfs():
    q = collections.deque()
    distances = [[-1] * m for _ in range(n)]
    
    for i in range(n):
        for j in range(m):
            if a[i][j] == 2:
                distances[i][j] = 0
                q.append((i, j))
    
    while q:
        x, y = q.popleft()
        for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
            nx = x + dx
            ny = y + dy
            if nx < 0 or nx >= n or ny < 0 or ny >= m or a[nx][ny] == 1 or distances[nx][ny] != -1:
                continue
            distances[nx][ny] = distances[x][y] + 1
            q.append((nx, ny))
    
    return distances

n, m = map(int, input().split())
a = [list(map(int, input().split())) for _ in range(n)]

distances = bfs()

for i in range(n):
    for j in range(m):
        print(distances[i][j], end=' ')
    print()

时间复杂度

BFS 算法的时间复杂度为 O(nm)。