К содержанию

Задание 23

Анализ графов

Граф из файла, кратчайший путь в ациклическом графе рекурсией с запоминанием, обязательные и запрещённые вершины.

6 подтем · 32 задачи + 5 дополнительных · повышенный · ≈ 12 мин

Подтема 1 из 6

Граф и путь

Что спрашивают в задании 23: строка файла — стрелка с весом, путь и его длина, почему в графе нет циклов.

Как устроена тема

В задании 23 дают текстовый файл. В каждой его строке — откуда можно перейти, куда и сколько стоит переход. Нужно найти самый дешёвый маршрут между двумя вершинами. Вот задача, которую мы решим в этой теме:

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

Всё задание — про одно: найти в графе из файла путь с наименьшей суммой весов и записать целую часть этой суммы. Разберём условие:

В условииЧто это значит
ориентированный графу ребра есть направление: строка «1 7 5.5» пускает из 1 в 7, но не обратно
взвешенныйу каждого ребра есть вес — цена перехода
ациклическийдвигаясь по стрелкам, нельзя вернуться туда, где уже был
в строке L, M и Wребро из L в M весом W; одна строка — одно ребро, заголовка в файле нет
длина кратчайшего путинаименьшая сумма весов, а не наименьшее число рёбер
вершины пронумерованы не подрядномер — только имя: вершина 100 не значит, что вершин сто
целая частьдробную часть отбрасывают у итоговой суммы, а не у каждого веса
пробелы и/или табуляциистроку разбивают line.split() без аргумента: он съедает любые пробелы

Сначала разберёмся на графе из восьми рёбер, который можно посчитать руками, потом напишем программу и решим задачу из файла. Тема состоит из пяти подтем и дополнительного урока — у каждой своя страница. Идём по ним по порядку:

  1. Граф и путь — ты сейчас здесь: ребро, путь и его длина.
  2. Лучший путь до цели — как найти кратчайший путь, не перебирая все.
  3. Программа с @cache — то же на Python; решим задачу темы: ответ 10211.
  4. Условия на путь — через вершину, в обход вершины, через ребро.
  5. Другие вопросы о путях — число путей, самый длинный путь, число рёбер.
  6. Условие на число рёбер — дополнительный урок: пути ровно из k рёбер.

Ребро и вес

Что значит строка 1 7 5.5?

Из вершины 1 можно перейти в вершину 7, и этот переход стоит 5.5. Такой переход называют ребром, а 5.5 — его весом. Обратно, из 7 в 1, эта строка не пускает: для этого нужна своя строка 7 1 …. На рисунке ребро — стрелка, вес подписан на ней.

Возьмём файл из восьми строк — его приводят как пример в условиях задания 23. На этом графе проверим каждый шаг темы:

100 12 1.06 7 7.06 1 1.01 7 5.57 100 2.04 100 8.01 100 12.01 4 2.5

Нарисуем его: каждая строка — стрелка от первого числа ко второму.

Учебный граф: шесть вершин и восемь рёбер. Порядок строк в файле неважен — важно, откуда и куда ведёт стрелка.

Номер вершины — только её имя. Вершин здесь шесть, хотя есть номер 100. И номера не обязаны расти по стрелкам: рёбра 100 → 12 и 6 → 1 ведут к меньшим номерам. Из 12 не выходит ни одной стрелки — дальше этой вершины идти некуда.

Путь и его длина

Как попасть из 1 в 100 и сколько это стоит?

Путь — цепочка стрелок, где каждая начинается там, где кончилась предыдущая. Длина пути — сумма весов его рёбер. Из 1 в 100 ведут три пути:

ПутьДлина
1 → 10012.0
1 → 7 → 1005.5 + 2.0 = 7.5
1 → 4 → 1002.5 + 8.0 = 10.5

Кратчайший — 1 → 7 → 100 длиной 7.5. В ответ задания пошла бы его целая часть: 7.

Кратчайший путь из 1 в 100: 5.5 + 2.0 = 7.5. Стрелка 1 → 100 — одно ребро, но стоит дороже: 12.

Число рёбер и длина — разные вещи: путь из одного ребра проиграл пути из двух. Пройди по графу сам: нажимай вершины по очереди, начиная с 1. Схема пропустит только ходы по стрелкам и посчитает длину.

1.07.01.05.52.08.012.02.5100126714
Песочница: путь собирается нажатием на вершины, длина — сумма весов пройденных рёбер.

Попробуй пойти против стрелки или найти путь короче 7.5 — не выйдет.

Без циклов

Зачем в условии слово «ациклический»?

Оно значит, что по стрелкам нельзя вернуться в вершину, где уже был. Поэтому любой путь когда-нибудь кончается, а путей — конечное число. Если бы в файле была ещё строка 100 1 …, можно было бы ходить по кругу 1 → 7 → 100 → 1 → … без конца. Такой круг называют циклом.

Цикл 1 → 7 → 100 → 1: по пунктирной стрелке можно вернуться в начало. В графах задания 23 таких стрелок нет.

Треугольник на рисунке — ещё не цикл. В учебном графе стрелки 1 → 7, 7 → 100 и 1 → 100 тоже образуют треугольник, но вернуться по ним в 1 нельзя. Цикл идёт только по направлению стрелок.

Без циклов путь из любой вершины либо доходит до цели, либо упирается в тупик — как в вершину 12. На этом держится всё решение следующих подтем.

Итого

  • Строка «a b w»ребро из a в b весом w; обратно — только своей строкой
  • Номер вершиныимя, а не количество вершин и не порядок
  • Путьстрелки цепочкой: каждая из конца предыдущей
  • Длина путисумма весов, а не число рёбер
  • Ациклический графпо стрелкам не вернуться; любой путь конечен
  • Учебный примеркратчайший путь 1 → 7 → 100, длина 7.5, ответ 7

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1
В файле есть строка 80 12 4.7. Можно ли перейти из 80 в 12? А из 12 в 80?
ОтветСкрыть ответ
Ответ
Из 80 в 12 — да, за 4.7. Из 12 в 80 — только если в файле есть своя строка 12 80 ….
Вопрос 2
Есть ли в учебном графе путь из 1 в 6?
ОтветСкрыть ответ
Ответ
Нет: в 6 не входит ни одна стрелка, из неё можно только выйти.
Вопрос 3
Найди все пути из 6 в 100 в учебном графе. Какой из них кратчайший?
ОтветСкрыть ответ
Ответ
Их четыре: 6 → 7 → 100 (9), 6 → 1 → 100 (13), 6 → 1 → 7 → 100 (8.5) и 6 → 1 → 4 → 100 (11.5). Кратчайший — 6 → 1 → 7 → 100 за 8.5, хотя рёбер в нём больше всех.
Вопрос 4
Рёбра графа: 2 9 1.5, 9 4 2.0, 4 2 0.5 и 9 6 3.0. Ациклический ли это граф?
ОтветСкрыть ответ
Ответ
Нет: по стрелкам 2 → 9 → 4 → 2 можно вернуться в 2.
Вопрос 5
Кратчайший путь из 1 в 100 в учебном графе стоит 7.5. Почему в ответ задания пошло бы 7, а не 8?
ОтветСкрыть ответ
Ответ
Нужна целая часть: дробную часть отбрасывают, а не округляют.

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Посчитайте вершины графа

Сколько вершин в графе с рёбрами 1 → 40, 40 → 7, 7 → 100 и 1 → 100?

Введите число.

Кратчайший путь перебором

Граф задан рёбрами:

1 20 2.41 7 6.020 7 1.37 100 3.220 100 8.01 100 15.0

Выпиши все пути из 1 в 100 и их длины. Запиши в ответ целую часть длины кратчайшего пути.

Введите целую часть найденной длины.

Сколько путей из 6

Учебный граф темы — файл из восьми строк:

100 12 1.06 7 7.06 1 1.01 7 5.57 100 2.04 100 8.01 100 12.01 4 2.5

Сколько разных путей ведёт из вершины 6 в вершину 100?

Введите число.

Кратчайший путь в небольшом графе

Граф задан рёбрами:

1 12 3.41 5 6.112 5 1.912 30 7.25 30 2.65 100 9.830 100 4.71 100 16.5

Найди длину кратчайшего пути из вершины 1 в вершину 100. В ответ запиши её целую часть.

Введите целую часть найденной длины.

Вершины на цикле

Граф задан рёбрами:

3 8 1.08 5 2.05 3 1.58 9 4.09 4 0.5

Сколько вершин лежит на направленном цикле?

Введите число.