В текстовом файле содержится описание ациклического ориентированного взвешенного графа.
В каждой строке файла записаны два натуральных числа (L, M) и одно положительное вещественное число (W). L и M — номера вершин графа, W — вес ребра, ведущего из вершины L в вершину M.
Таким образом, количество строк в файле равно количеству рёбер в графе.
Две вершины графа не могут быть соединены более чем одним ребром.
Найдите и запишите в ответе целую часть длины кратчайшего пути из вершины с номером 1 в вершину с номером 100.
Существование хотя бы одного такого пути гарантируется.
Под длиной кратчайшего пути понимается минимальная сумма весов рёбер, составляющих путь.
Для выполнения этого задания следует написать программу.
Вершины графа могут быть пронумерованы не подряд.
L ≤ 1000, M ≤ 1000; W ≤ 10 000.
Количество строк в файле не превосходит 200.
Числа в строках разделены произвольным ненулевым количеством пробелов и/или табуляций.

Типовой пример организации данных во входном файле для графа на рисунке
|
1 2 3 4 5 6 7 8 |
100 12 1.0 6 7 7.0 6 1 1.0 1 7 5.5 7 100 2.0 4 100 8.0 1 100 12.0 1 4 2.5 |
Для приведённого примера верным ответом будет 7.
Типовой пример имеет иллюстративный характер.
Для выполнения задания используйте данные из прилагаемого файла.

Ответ:
Демонстрационный вариант ЕГЭ 2027 по информатике – задание №23
Решение:
Для решения задачи удобно использовать алгоритм Дейкстры.
Он позволяет найти кратчайшее расстояние от одной вершины графа до всех остальных.
В нашей задаче нужно найти минимальное расстояние от вершины 1
до вершины 100.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from heapq import * f = open('23.txt') g = {} for line in f: a, b, w = line.split() a = int(a) b = int(b) w = float(w) if a not in g: g[a] = [] g[a].append((b, w)) d = {1: 0} q = [(0, 1)] while q: dist, v = heappop(q) if dist != d[v]: continue for to, w in g.get(v, []): nd = dist + w if to not in d or nd < d[to]: d[to] = nd heappush(q, (nd, to)) print(int(d[100])) |
Разбор программы
Сначала подключаем функции для работы с очередью с приоритетом:
|
1 |
from heapq import * |
Очередь с приоритетом позволяет каждый раз быстро получать вершину,
до которой на текущий момент найдено наименьшее расстояние.
Открываем файл:
|
1 |
f = open('23.txt') |
Создаём словарь g, в котором будем хранить граф:
|
1 |
g = {} |
Каждая строка файла содержит три значения:
номер начальной вершины, номер конечной вершины и вес ребра.
|
1 2 |
for line in f: a, b, w = line.split() |
Например, строка
|
1 |
1 7 5.5 |
означает, что существует ребро
|
1 |
1 → 7 |
с весом 5.5.
Номера вершин преобразуем в целые числа,
а вес ребра — в вещественное число:
|
1 2 3 |
a = int(a) b = int(b) w = float(w) |
Если вершины a ещё нет в словаре, создаём для неё пустой список:
|
1 2 |
if a not in g: g[a] = [] |
После этого добавляем в список вершину, в которую ведёт ребро,
и его вес:
|
1 |
g[a].append((b, w)) |
Например, если в файле есть строки
|
1 2 3 |
1 7 5.5 1 4 2.5 1 100 12.0 |
то в словаре получится:
|
1 |
g[1] = [(7, 5.5), (4, 2.5), (100, 12.0)] |
Массив расстояний
Создаём словарь d.
В нём будем хранить минимальное найденное расстояние
от вершины 1 до каждой вершины.
|
1 |
d = {1: 0} |
Расстояние от вершины 1 до самой себя равно 0.
Также создаём очередь:
|
1 |
q = [(0, 1)] |
Пара (0, 1) означает:
расстояние до вершины 1 равно 0.
Алгоритм Дейкстры
Пока очередь не пуста, извлекаем из неё элемент
с минимальным расстоянием:
|
1 2 |
while q: dist, v = heappop(q) |
Здесь:
dist— расстояние от вершины 1 до текущей вершины;v— номер текущей вершины.
В очередь одна и та же вершина может попасть несколько раз.
Если найденное ранее расстояние уже меньше, старую запись пропускаем:
|
1 2 |
if dist != d[v]: continue |
Теперь перебираем все рёбра, выходящие из вершины v:
|
1 |
for to, w in g.get(v, []): |
Здесь:
to— вершина, в которую ведёт ребро;w— вес этого ребра.
Метод
|
1 |
g.get(v, []) |
возвращает список всех рёбер, выходящих из вершины v.
Если из вершины нет исходящих рёбер, возвращается пустой список.
Вычисляем новое расстояние:
|
1 |
nd = dist + w |
То есть к уже найденному расстоянию до вершины v
добавляем вес следующего ребра.
Далее проверяем:
|
1 |
if to not in d or nd < d[to]: |
Условие выполняется в двух случаях:
- мы ещё ни разу не находили путь до вершины
to; - новый путь оказался короче уже найденного.
Если найден более короткий путь, сохраняем новое расстояние:
|
1 |
d[to] = nd |
и добавляем эту вершину в очередь:
|
1 |
heappush(q, (nd, to)) |
Пример работы
Пусть имеются такие пути:
|
1 2 3 4 5 |
1 → 100 = 12 1 → 4 → 100 = 2.5 + 8 = 10.5 1 → 7 → 100 = 5.5 + 2 = 7.5 |
Сначала программа может найти прямой путь:
|
1 |
d[100] = 12 |
Затем найдётся более короткий путь через вершину 4:
|
1 |
d[100] = 10.5 |
После этого найдётся ещё более короткий путь через вершину 7:
|
1 |
d[100] = 7.5 |
Таким образом, кратчайший путь имеет длину 7.5.
Получение ответа
По условию требуется записать не само вещественное число,
а его целую часть.
Поэтому используем функцию int():
|
1 |
print(int(d[100])) |
Для значения
|
1 |
7.5 |
получим:
|
1 |
7 |
Следовательно, для приведённого в условии примера ответ:
7.
Ответ: 10971