Перевод (Русский)

<topic>

## Восстановление кратчайшего пути

start = int(input())                    # начальная вершина
d = [-1] * n                            # расстояние от начальной вершины
p = [-1] * n                            # родительская вершина
q = deque([start])                      # очередь вершин
d[start] = 0                            # расстояние от start до start равно 0

while q:                                # пока очередь не пуста
    v = q.popleft()                     # достаём вершину из очереди
    print(v, end=' ')                   # выводим вершину
    for to in g[v]:                     # для всех вершин, смежных с v
        if d[to] == -1:                 # если вершина ещё не посещена
            d[to] = d[v] + 1            # (start -> to) = (start -> v) + 1
            p[to] = v                   # родитель вершины to — это v
            q.append(to)                # добавляем вершину в очередь

# Восстановление пути от start до end
end = int(input())                      # конечная вершина
path = []                               # путь от start до end
while end != -1:                        # пока есть родительская вершина
    path.append(end)                    # добавляем вершину в путь
    end = p[end]                        # переходим к родительской вершине

print(*path[::-1], sep=' -> ')          # выводим путь в обратном порядке

Итак, после добавления каждой вершины в очередь мы фиксируем её родителя в массиве p и в самом конце восстанавливаем маршрут, двигаясь от конечной вершины к начальной. В итоге путь нужно вывести в обратном порядке, потому что мы начинаем восстановление с конца и переходим по родителям к началу. Чтобы пройти от start до end, нам нужно развернуть полученный список.

Рассмотрим работу алгоритма на нескольких примерах:

n = 4, e = 4

На вход подаются пары (a, b): [(0, 1), (0, 2), (1, 2), (3, 2)]

Начальная вершина — 3, конечная вершина — 0

  1. p = [-1, -1, -1, -1], q = [3]

  2. v = 3, q = [] → добавить в очередь всех соседей, которые ещё не использованы

  3. p = [-1, -1, 3, -1], q = [2]

  4. v = 2, q = [] → добавить в очередь всех соседей, которые ещё не использованы

  5. p = [2, 2, 3, -1], q = [0, 1]

  6. v = 0, q = [1] → добавить в очередь всех соседей, которые ещё не использованы

  7. v = 1, q = [] → добавить в очередь всех соседей, которые ещё не использованы

  8. Восстановить путь

  9. end = 0 → end = 2 → end = 3

  10. Выводим 3 → 2 → 0

Обратите внимание: если в конце работы алгоритма d[end] всё ещё равно -1, это означает, что дойти до вершины end было невозможно.

Задача: Найти кратчайший маршрут

Интернет — это сеть компьютеров, соединённых друг с другом и способных передавать данные. Здесь эти компьютеры пронумерованы от 1 до n, и у нас есть информация о том, какие из них связаны напрямую. Алиса хочет отправить сообщение Бобу и желает выбрать путь, который позволит сделать это как можно быстрее. Значит, маршрут должен быть как можно короче.

Компьютеры Алисы и Боба имеют номера a и b соответственно. Требуется найти оптимальную последовательность компьютеров, по которым сообщение пройдёт от Alice к Bob за наименьшее время.

Входные данные

В первой строке содержатся два целых числа n (1 ≤ n ≤ 100 000) и e (1 ≤ e ≤ 100 000), обозначающие количество компьютеров и количество соединений в сети.

Во второй строке заданы два числа a и b (1 ≤ a, b ≤ n).

В следующих e строках содержатся пары целых чисел c1, c2 (1 ≤ c1, c2 ≤ n), указывающие, что компьютер c1 соединён с компьютером c2 и наоборот.

Выходные данные

Программа должна вывести самый короткий маршрут передачи сообщения, при этом номера компьютеров следует разделять пробелом. Если существует несколько оптимальных вариантов, можно вывести любой из них.

Примеры

Вход

Выход

5 5 1 5 1 2 2 3 1 3 3 4 3 5

1 3 5

5 6 1 5 1 2 2 3 2 4 3 4 4 5 3 5

1 2 4 5

Constraints

Time limit: 2 seconds

Memory limit: 512 MB

Output limit: 1 MB

To check your solution you need to sign in
Sign in to continue