Перейти к содержимому

Задание 23 ЕГЭ по информатике 2027: кратчайший путь в графе

Задание 23до 1 баллакратчайший путь в графе
Раздел
Теоретические основы информатики
Максимальный балл
1 балл
Уровень
повышенный
Что проверяет
Умение решать алгоритмические задачи, связанные с анализом графов (задачи построения оптимального пути между вершинами графа, определения количества различных путей между вершинами ориентированного ациклического графа)
Что нужно сделать
В файле — рёбра взвешенного ориентированного графа. Найти длину кратчайшего пути или число путей между вершинами.
Как записать ответ
только число: целое, без пробелов и единиц измерения
Время
Около 12 минут по обобщённому плану ФИПИ
Элемент кодификатора
2.13
Компьютер
Нужна программа или электронная таблица: на станции КЕГЭ — среды программирования на C#, C++, Pascal, Java, Python и редактор таблиц
Файл к заданию
текстовый файл .txt — его читает программа
В 2026 году
Такого задания не было — оно появилось в КИМ 2027 года

Задание 23 ЕГЭ по информатике 2027 года — новое: в КИМ 2026 года под этим номером было «Умение анализировать ход исполнения алгоритма», теперь это задание 13. По формулировке ФИПИ, 23 проверяет «умение решать алгоритмические задачи, связанные с анализом графов»: построить оптимальный путь между вершинами или посчитать число различных путей в ориентированном ациклическом графе.

К заданию прилагается текстовый файл: в каждой строке — номера двух вершин и вес ребра, строк до 200. Уровень повышенный, по обобщённому плану — 12 минут, за верный ответ 1 балл. В демоверсии сказано: «Для выполнения этого задания следует написать программу». Методические рекомендации ФИПИ советуют «обратить внимание на новый тип задания 23» и называют поиск путей в графах среди тем, которым нужно «уделить особое внимание». Ниже — три типа задания с решением на Python: код запускается на странице на файле примера.

Ищете задание 23 по нумерации 2026 года? Тогда под этим номером было другое задание — «число программ исполнителя». В КИМ 2027 года это задание 13.

Тренажёр задания 23

Десять заданий номера 23 из банка тренажёра — с файлами, как на станции КЕГЭ. Решайте в песочнице Python прямо на странице или у себя; ответ проверяется по ключу, после проверки — верный ответ, разбор и решение на Python, а при ошибке — разбор от ИИ. Кнопка «Ещё 5 таких» у типа задания ниже даёт задания одного типа.

Загружаем задание…

Задание 23 вместе с остальными — в вариантах целиком.

Типы задания 23 с решением

Кратчайший путь между двумя вершинами

Пример условия

В файле — рёбра ациклического ориентированного графа: в строке номера вершин L и M и вес W ребра L → M. Найдите целую часть длины кратчайшего пути из вершины 1 в вершину 512.

16    32    5.0
1     16    14.0
32    46    2.0
16    512   11.0
46    512   8.0
32    512   9.0

Для этого примера ответ — 25.

Задание выполняется с использованием прилагаемого файла

23.txt3 КБ

1. Читаем рёбра в словарь: вершина → список пар (куда ведёт ребро, вес). 2. Алгоритм Дейкстры: в очереди с приоритетом лежат пары (расстояние, вершина); достаём ближайшую и улучшаем расстояния до её соседей. 3. Устаревшую пару с расстоянием больше найденного пропускаем. 4. Печатаем целую часть расстояния до конечной вершины.

На примере: из 1 в 512 ведут пути 1 → 16 → 512 (14 + 11 = 25), 1 → 16 → 32 → 512 (28) и 1 → 16 → 32 → 46 → 512 (29); кратчайший — 25. Это тип задания из демоверсии 2027 года.

Решение на Python
import heapq
from collections import defaultdict

graph = defaultdict(list)  # вершина -> [(куда ведёт ребро, вес)]
with open('23.txt') as f:
    for line in f:
        parts = line.split()  # любое число пробелов и табуляций
        if len(parts) == 3:
            l, m, w = int(parts[0]), int(parts[1]), float(parts[2])
            graph[l].append((m, w))

# алгоритм Дейкстры: все веса положительны
dist = {1: 0.0}
heap = [(0.0, 1)]
while heap:
    d, v = heapq.heappop(heap)
    if d > dist[v]:
        continue  # устаревшая запись: до v уже нашли путь короче
    for u, w in graph[v]:
        if d + w < dist.get(u, float('inf')):
            dist[u] = d + w
            heapq.heappush(heap, (d + w, u))

print(int(dist[512]))  # целая часть, не round()

Ответ на приложенном файле: 1215

Количество различных путей

Пример условия

В файле — рёбра ациклического ориентированного графа в том же формате. Найдите количество различных путей из вершины 1 в вершину 100. Два пути различны, если отличаются хотя бы одним ребром.

69    100   3.0
100   2     11.0
90    69    5.0
69    2     7.0
14    100   13.0
69    14    8.0
1     90    14.0

Для этого примера ответ — 2.

Задание выполняется с использованием прилагаемого файла

23.txt1,7 КБ

1. Веса не нужны: для каждой вершины запоминаем, из каких вершин в неё ведут рёбра. 2. Число путей из 1 в v — сумма чисел путей во все такие вершины; в саму вершину 1 — один путь. 3. Функция ways(v) считает это рекурсивно, а lru_cache запоминает ответы: иначе вершины пересчитываются экспоненциально много раз. Граф ациклический, поэтому рекурсия не зациклится.

На примере: в 100 входят рёбра из 69 и 14, в 14 — из 69, в 69 — из 90, в 90 — из 1. ways(90) = ways(69) = 1, ways(14) = 1, ways(100) = 1 + 1 = 2.

Решение на Python
from functools import lru_cache
from collections import defaultdict

incoming = defaultdict(list)  # вершина -> из каких вершин в неё ведут рёбра
with open('23.txt') as f:
    for line in f:
        parts = line.split()
        if len(parts) == 3:
            incoming[int(parts[1])].append(int(parts[0]))


@lru_cache(maxsize=None)
def ways(v):
    # путей из 1 в v столько, сколько их во все вершины, откуда есть ребро в v
    if v == 1:
        return 1
    return sum(ways(u) for u in incoming[v])


print(ways(100))

Ответ на приложенном файле: 70

Кратчайший путь через обязательную вершину

Пример условия

В файле — рёбра ациклического ориентированного графа в том же формате. Найдите целую часть длины кратчайшего пути из вершины 42 в вершину 100, проходящего через вершину 105.

96    100   9.0
96    51    6.5
42    96    14.5
100   3     3.5
96    105   5.0
51    100   14.5
51    3     7.0
105   51    15.0

Для этого примера ответ — 49.

Задание выполняется с использованием прилагаемого файла

23.txt2,9 КБ

1. Путь через 105 распадается на две независимые части: 42 → 105 и 105 → 100. Каждую берём кратчайшей и складываем. 2. Строим топологический порядок алгоритмом Кана: сначала вершины без входящих рёбер, затем те, чьи входящие рёбра уже обработаны. 3. Функция shortest(start) за один проход по порядку находит расстояния от start до всех вершин. 4. Ответ — int(shortest(42)[105] + shortest(105)[100]).

На примере: 42 → 96 → 105 стоит 14,5 + 5 = 19,5, а из 105 в 100 путь один — через 51: 15 + 14,5 = 29,5. Сумма 49. Без обязательной вершины кратчайший путь 42 → 96 → 100 был бы 23,5 — неверно.

Решение на Python
from collections import defaultdict, deque

graph = defaultdict(list)
indeg = defaultdict(int)  # сколько рёбер входит в вершину
nodes = set()
with open('23.txt') as f:
    for line in f:
        parts = line.split()
        if len(parts) == 3:
            l, m, w = int(parts[0]), int(parts[1]), float(parts[2])
            graph[l].append((m, w))
            indeg[m] += 1
            nodes |= {l, m}

# топологический порядок (алгоритм Кана): каждое ребро ведёт «вперёд»
queue = deque(v for v in nodes if indeg[v] == 0)
order = []
while queue:
    v = queue.popleft()
    order.append(v)
    for u, w in graph[v]:
        indeg[u] -= 1
        if indeg[u] == 0:
            queue.append(u)


def shortest(start):
    # расстояния от start за один проход в топологическом порядке
    dist = {v: float('inf') for v in nodes}
    dist[start] = 0.0
    for v in order:
        for u, w in graph[v]:
            dist[u] = min(dist[u], dist[v] + w)
    return dist


# путь через 105 = кратчайший 42 → 105 + кратчайший 105 → 100
print(int(shortest(42)[105] + shortest(105)[100]))

Ответ на приложенном файле: 1671

Шаблон кода на Python

Кратчайший путь в графе из файла

В строке файла — ребро «откуда куда вес». Алгоритм Дейкстры с heapq находит расстояния от одной вершины до всех; для неориентированного графа добавьте ребро в обе стороны.

Python
import heapq
from collections import defaultdict

graph = defaultdict(list)
with open('23.txt') as f:
    for line in f:
        if line.split():
            u, v, w = line.split()
            graph[int(u)].append((int(v), float(w)))

start, finish = 1, 5
dist = {start: 0.0}
heap = [(0.0, start)]
while heap:
    d, u = heapq.heappop(heap)
    if d > dist[u]:
        continue
    for v, w in graph[u]:
        if d + w < dist.get(v, float('inf')):
            dist[v] = d + w
            heapq.heappush(heap, (d + w, v))

print(int(dist[finish]))   # целая часть длины пути
Файл-пример 23.txt
1 2 2.5
1 3 1.2
3 2 0.8
2 4 3.1
3 4 5.0
4 5 1.0
Вывод на файле-примере
6

Шаблоны кода ко всем заданиям

Как выполнять задание

  1. Сохраните файл задания в рабочую папку и откройте его по имени из условия (например, demo_23.txt или 23.txt). Вершины пронумерованы не подряд — храните граф в словаре.
  2. Читайте строку через line.split() без аргумента: числа разделены «произвольным ненулевым количеством пробелов и/или табуляций». Номера вершин — int, вес — float.
  3. Выберите алгоритм по вопросу: кратчайший путь — Дейкстра или проход в топологическом порядке; число путей — сумма по входящим рёбрам; путь через вершину — два кратчайших пути подряд.
  4. Сначала запустите программу на типовом примере из условия и сравните ответ с названным, только потом — на файле.
  5. В ответ идёт целая часть длины: int(…), а не round(…). Ответ — одно целое число.

Что нужно знать

  • Ориентированный ациклический граф. Двигаясь по рёбрам, нельзя вернуться в пройденную вершину, поэтому вершины можно выстроить в топологический порядок: каждое ребро ведёт вперёд. К моменту обработки вершины всё, что в неё входит, уже посчитано.
  • Кратчайший путь. Расстояние до начальной вершины — 0, до остальных — бесконечность; ребро L → M с весом W улучшает расстояние до M, если dist[L] + W меньше. Дейкстра работает на любом графе с неотрицательными весами, проход в топологическом порядке — только на ациклическом, но проще.
  • Число путей. Путей из 1 в вершину M столько, сколько в сумме путей во все вершины, откуда есть ребро в M; в саму вершину 1 — один путь.
  • Путь через вершину. Кратчайший путь из A в B через C — это кратчайший A → C плюс кратчайший C → B.

Демоверсию КЕГЭ 2027 с файлом и песочницей Python можно пройти на сайте.

Как оценивается

Проверка автоматическая, по ключу: ответ должен быть записан в форме из условия и полностью совпасть с эталоном. Код и черновики не проверяют — значение имеет только ответ. За верный ответ — 1 балл, частичного балла нет.

Критерии всех заданий экзамена — на странице критериев ЕГЭ.

Разбор задания демоверсии 2027

В демоверсии 2027 года граф задан файлом demo_23.txt: спрашивают целую часть длины кратчайшего пути из вершины 1 в вершину 100. Типовой пример в условии — восемь рёбер: 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).

Проверим руками. Из 1 в 100 ведут три пути: прямое ребро длиной 12; 1 → 7 → 100 длиной 5,5 + 2 = 7,5; 1 → 4 → 100 длиной 2,5 + 8 = 10,5. Кратчайший — 7,5, целая часть — 7. Вершина 6 на ответ не влияет: в неё нет пути из 1. Ловушка с округлением: round(7.5) дал бы 8.

На файле демоверсии та же программа, но открывающая demo_23.txt, с вершиной 100 вместо 512 печатает 10971 — ключ ФИПИ.

Типичные ошибки

Пробел вместо split() без аргумента

Если между числами несколько пробелов или табуляция, line.split(' ') даёт пустые элементы, и int('') падает. Условие обещает «произвольное ненулевое количество пробелов и/или табуляций» — пишите line.split().

Вес прочитан как int

Веса дробные: «5.0», «5.5». int('5.5') падает с ValueError, а если отбросить дробную часть заранее, кратчайший путь получится не тот. Номера вершин — int, вес — float.

round() вместо целой части

Спрашивают целую часть длины. На примере демоверсии путь 7,5: int(7.5) = 7 — верно, round(7.5) = 8 — неверно, хотя путь найден правильно.

Список вместо словаря

Вершины «могут быть пронумерованы не подряд», номер до 1000. Список dist длиной «число вершин из файла» падает с IndexError на вершине 512. Словарь или список длины 1001 этой проблемы не имеют.

Число путей считают как сумму весов

В вопросе о количестве путей веса не нужны: складываются числа путей во входящие вершины. Если программа печатает дробное число — она считает не то.

Вопросы и ответы

Можно ли решить задание 23 без программы?

Формально ход решения не проверяют, но в файле до 200 рёбер, и демоверсия прямо указывает: «Для выполнения этого задания следует написать программу». Вручную считают только типовой пример — как проверку программы.

Какой алгоритм нужен: Дейкстра или динамика по графу?

Для кратчайшего пути подходят оба: веса положительные, граф ациклический; методические рекомендации ФИПИ называют Дейкстру. Для числа путей Дейкстра не нужна — нужен подсчёт по входящим рёбрам в топологическом порядке или рекурсия с запоминанием.

Что было заданием 23 в 2026 году?

В КИМ 2026 года 23 проверяло анализ хода исполнения алгоритма — сколько программ исполнителя переводят одно число в другое. В 2027 году эта тема перешла в задание 13, а 23 стало заданием на графы с файлом.

Можно ли на экзамене подключить библиотеку для графов?

Сторонние библиотеки на станции КЕГЭ не обещаны: перечень ПО региона доводят до участников не позднее 1 марта. Поэтому решения здесь используют только стандартную библиотеку Python: heapq, collections, functools.

Другие задания раздела «Теоретические основы информатики»

По демоверсии, спецификации и кодификатору ФИПИ 2027
Обновлено:

Все задания ЕГЭ по информатике →