Кратчайший путь в ациклическом графе
НЕТ ВОЙНЕ |
24 февраля 2022 года российское руководство во главе с Владимиром Путиным развязало агрессивную войну против Украины. В глазах всего мира это военное преступление совершено от лица всей страны, всех россиян. Будучи гражданами Российской Федерации, мы против своей воли оказались ответственными за нарушение международного права, военное вторжение и массовую гибель людей. Чудовищность совершенного преступления не оставляет возможности промолчать или ограничиться пассивным несогласием. Мы убеждены в абсолютной ценности человеческой жизни, в незыблемости прав и свобод личности. Режим Путина — угроза этим ценностям. Наша задача — обьединить все силы для сопротивления ей. Эту войну начали не россияне, а обезумевший диктатор. И наш гражданский долг — сделать всё, чтобы её остановить. Антивоенный комитет России |
Распространяйте правду о текущих событиях, оберегайте от пропаганды своих друзей и близких. Изменение общественного восприятия войны - ключ к её завершению. |
meduza.io, Популярная политика, Новая газета, zona.media, Майкл Наки. |
Задача: |
Пусть дан ациклический ориентированный взвешенный граф. Требуется найти вес кратчайшего пути из в . |
Решение
Воспользуемся принципом оптимальности на префиксе.
Пусть — функция, где — вес кратчайшего пути из в . Ясно, что равен . Пусть — вес ребра из в . Будем обходить граф в порядке топологической сортировки. Получаем следующие соотношения:
Так как мы обходим граф в порядке топологической сортировки, то на -ом шаге всем ( такие, что существует ребро из в ) уже присвоены оптимальные ответы, и, следовательно, также будет присвоен оптимальный ответ.
Реализация
Реализуем данный алгоритм:
//w — матрица смежности //d — массив кратчайших расстояний //p — массив индексов вершин графа в порядке топологической сортировки for i = 1 .. n d[i] =d[u] = 0 // где u — начальная вершина
p = topSort(w) //топологическая сортировка графа for i = 1 .. n for j: есть ребро из p[i] в j d[j] = min(d[j], d[p[i]] + w[p[i]][j])
Пример
Пусть дана матрица смежности графа
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
1 | - | - | - | - | 2 | - | - | - |
2 | 1 | - | 1 | - | 4 | 3 | - | - |
3 | - | - | - | - | - | 1 | - | - |
4 | - | - | - | - | - | - | - | - |
5 | - | - | - | 3 | - | - | - | 1 |
6 | - | - | - | 5 | - | - | 2 | - |
7 | - | - | - | 2 | - | - | - | - |
8 | - | - | - | 1 | - | - | - | - |
Требуется найти вес кратчайшего пути из 2 в 4.
Массив будет выглядеть следующим образом:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
2 | 3 | 6 | 7 | 1 | 5 | 8 | 4 |
Массив
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
1 | 0 | 1 | 5 | 3 | 2 | 4 | 4 |
Ответ равен
.Альтернативный способ решения
Решим задачу, используя обход в ширину. Для этого заведем массив, в котором будем хранить веса кратчайших расстояний от начальной вершины до всех остальных. Совершая обход по графу, будем в каждой вершине для всех ее потомков проверять, уменьшится ли вес кратчайшего пути до сына, если пройти через текущую вершину. Если да, то весу кратчайшего расстояния до сына присваиваем значение, равное сумме веса кратчайшего расстояния до текущей вершины и стоимости прохода по ребру между вершиной и ее сыном. В силу особенности обхода графа, обновление весов кратчайших путей до сыновей вершины происходит только тогда, когда для нее уже найден оптимальный ответ.