Когда алгоритм BFS начинается с одной вершины и постепенно расширяет область поиска, он может найти кратчайший путь от стартовой вершины до всех остальных в графе. Для этого нам надо чуть изменить исходный алгоритм. Мы будем использовать массив расстояний d, который изначально будет заполнен значениями -1. Если значение вершины равно -1, значит, эта вершина ещё не посещена. Если же значение неотрицательное, оно указывает расстояние от стартовой вершины до текущей:
from collections import deque
n, e = map(int, input().split()) # n: вершины, e: ребра
g = [[] for _ in range(n)] # граф - список смежности
for _ in range(e): # считываем рёбра
a, b = map(int, input().split()) # a -> b и b -> a
g[a].append(b)
g[b].append(a)
start = int(input()) # стартовая вершина
d = [-1] * n # расстояние от стартовой вершины
q = deque([start]) # очередь вершин
d[start] = 0 # расстояние от start до start равно 0
while q: # пока очередь не пуста
v = q.popleft() # извлекаем вершину из очереди
print(v, end=' ') # выводим вершину
for to in g[v]: # для всех соседних вершин
if d[to] == -1: # если вершина ещё не посещена
d[to] = d[v] + 1 # (start -> to) = (start -> v) + 1
q.append(to) # добавляем вершину в очередь
print(d)
Здесь мы сначала инициализируем массив расстояний d значениями -1, что служит признаком того, что ни одна вершина не была использована. Затем ставим d[start] = 0, указывая на то, что расстояние от вершины start до неё же равно 0.
По мере работы алгоритма значения в массиве d обновляются, давая нам расстояние для каждой вершины, начиная с start.
Давайте посмотрим, как алгоритм работает на нескольких входных данных:
n = 4, e = 4
Пары входных данных a, b: [(0, 1), (0, 2), (1, 2), (3, 2)]
Начальная вершина: 3
d = [-1, -1, -1, 0], q = [3]
v = 3, q = [] → добавляем всех соседей, которые ещё не использовались, в очередь
d = [-1, -1, 1, 0], q = [2]
v = 2, q = [] → добавляем всех соседей, которые ещё не использовались, в очередь
d = [2, 2, 1, 0], q = [0, 1]
v = 0, q = [1] → добавляем всех соседей, которые ещё не использовались, в очередь
v = 1, q = [] → добавляем всех соседей, которые ещё не использовались, в очередь
Готово
n = 5, e = 4
Пары входных данных a, b: [(0, 1), (0, 2), (1, 2), (3, 4)]
Начальная вершина: 0
d = [0, -1, -1, -1, -1], q = [0]
v = 0, q = [] → добавляем всех соседей, которые ещё не использовались, в очередь
d = [0, 1, 1, -1, -1], q = [1, 2]
v = 1, q = [2] → добавляем всех соседей, которые ещё не использовались, в очередь
v = 2, q = [] → добавляем всех соседей, которые ещё не использовались, в очередь
Готово
Notice how nodes 3 and 4 were never visited.
They were not connected to the initial node 0.
Задача: найти длину кратчайшего пути
Дан неориентированный граф с v вершинами и e рёбрами. Требуется вычислить кратчайший путь между вершинами 1 и v. Если они не связаны, необходимо вывести Impossible.
Входные данные
В первой строке даны два целых числа v (1 ≤ v ≤ 100 000) и e (1 ≤ e ≤ 100 000).
В последующих e строках содержатся пары целых чисел v1, v2 (1 ≤ v1, v2 ≤ v), указывающие, что существует ребро между вершинами v1 и v2 (и наоборот).
Вывод
Программа должна вывести длину кратчайшего пути между 1 и v.