<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=93.175.2.232&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=93.175.2.232&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/93.175.2.232"/>
		<updated>2026-05-04T13:43:46Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D1%80%D0%B4%D0%B0-%D0%91%D0%B5%D0%BB%D0%BB%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=48915</id>
		<title>Алгоритм Форда-Беллмана</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D1%80%D0%B4%D0%B0-%D0%91%D0%B5%D0%BB%D0%BB%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=48915"/>
				<updated>2015-07-05T08:52:08Z</updated>
		
		<summary type="html">&lt;p&gt;93.175.2.232: /* Корректность */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Для заданного взвешенного графа &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt; алгоритм находит кратчайшие пути из заданной вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; до всех остальных вершин.&lt;br /&gt;
В, случае, когда в графе &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; содержатся отрицательные циклы, достижимые из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, алгоритм сообщает, что кратчайших путей не существует.&lt;br /&gt;
&lt;br /&gt;
==Введение==&lt;br /&gt;
Сначала стоит вспомнить формулу для количества путей длины &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;tex&amp;gt; d[k][u] = \sum\limits_{v : vu \; \in E}  d[k-1][v] &amp;lt;/tex&amp;gt;&lt;br /&gt;
Теперь перепишем ее для пути кратчайшей длины. &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} стартовая вершина.&lt;br /&gt;
&amp;lt;tex&amp;gt; d[k][u] = \min\limits_{v : vu \; \in E}(d[k-1][v] \: + \: \omega[uv])&amp;lt;/tex&amp;gt;,  при этом &amp;lt;tex&amp;gt;d[0][s] = 0&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;d[0][u] = +\infty &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=Если существует кратчайший путь от &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt; \rho(s, \, t) \: = \: \min\limits_{k = 0..n-1} d[k][t]&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=Пусть кратчайший путь состоит из &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; ребер, тогда корректность формулы следует из динамики, приведенной ниже.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
Используя приведенные формулы, алгоритм можно реализовать методом динамического программирования.&lt;br /&gt;
&lt;br /&gt;
  '''for''' &amp;lt;tex&amp;gt;(k = 0 \; .. \; n-2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
     '''for''' &amp;lt;tex&amp;gt;(v \in V)&amp;lt;/tex&amp;gt;&lt;br /&gt;
        '''for''' &amp;lt;tex&amp;gt;(u : vu \; \in E)&amp;lt;/tex&amp;gt;&lt;br /&gt;
           &amp;lt;tex&amp;gt;d[k+1][u] \gets \min(d[k + 1][u], \; d[k][v] + \omega(uv))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также релаксацию можно свести к одномерному случаю (одномерный массив будем обозначать &amp;lt;tex&amp;gt;d'&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&amp;lt;tex&amp;gt;d'[u] \gets \min(d'[u], \; d'[v] + \omega(vu))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Корректность==&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=Пусть &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt; — взвешенный ориентированный граф, &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; — стартовая вершина.&lt;br /&gt;
Тогда после завершения &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций цикла &amp;lt;tex&amp;gt;for(k)&amp;lt;/tex&amp;gt; выполняется неравенство &amp;lt;tex&amp;gt; \rho(s, u) \leqslant d'[u] \leqslant  \min\limits_{i = 0..k} d[i][u]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Воспользуемся индукцией по &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''База индукции''' &lt;br /&gt;
:При &amp;lt;tex&amp;gt;k = 0&amp;lt;/tex&amp;gt; выполнено: &amp;lt;tex&amp;gt;\rho(s, u) \leqslant +\infty \leqslant +\infty &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Индукционный переход'''&lt;br /&gt;
:Сначала докажем, что &amp;lt;tex&amp;gt; \rho(s, u) \leqslant d'[u]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Пусть после &amp;lt;tex&amp;gt;k - 1 &amp;lt;/tex&amp;gt; итерации выполняется &amp;lt;tex&amp;gt;\rho(s, u) \leqslant d'[u] \leqslant \min\limits_{i=0..k-1} d[i][u]&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Тогда после &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций &amp;lt;tex&amp;gt; \rho(s, v) = \min\limits_{u \in V} (\rho(s, u) + \omega(uv)) \leqslant \min\limits_{u \in V} (d'[u] + \omega(uv)) = d'[v]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Переходим ко второму неравенству.&lt;br /&gt;
:Теперь возможно два случая:&lt;br /&gt;
:#&amp;lt;tex&amp;gt;\min\limits_{i = 0..k+1} d[i][u] = d[k+1][u]&amp;lt;/tex&amp;gt;&lt;br /&gt;
:#&amp;lt;tex&amp;gt;\min\limits_{i = 0..k+1} d[i][u] = d[j][u] =\min\limits_{i = 0..j} \; d[i][u]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Рассмотрим 1 случай:&lt;br /&gt;
::&amp;lt;tex&amp;gt;\min\limits_{i = 0..k+1} d[i][u] = d[k+1][u]&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
::&amp;lt;tex&amp;gt;d'[u] \leqslant d'[v] + \omega(vu) \leqslant d[k][v] + \omega(vu) = d[k+1][u]&amp;lt;/tex&amp;gt;&lt;br /&gt;
::&amp;lt;tex&amp;gt;\vartriangleleft&amp;lt;/tex&amp;gt;&lt;br /&gt;
:2 случай расписывается аналогично.&lt;br /&gt;
&lt;br /&gt;
Таким образом переход выполнен и &amp;lt;tex&amp;gt;\rho(s, u) \leqslant d'[u] \leqslant  \min\limits_{i = 0..k} d[i][u]&amp;lt;/tex&amp;gt; выполняется.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Реализация алгоритма и ее корректность==&lt;br /&gt;
 '''Bellman_Ford(G, s)'''&lt;br /&gt;
    '''for''' для каждой &amp;lt;tex&amp;gt;v \in V&amp;lt;/tex&amp;gt;&lt;br /&gt;
       &amp;lt;tex&amp;gt; d[v] \leftarrow \mathcal {1} &amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;d[s] \leftarrow 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''for''' &amp;lt;tex&amp;gt; i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt; |V| - 1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
       '''for''' для каждого ребра &amp;lt;tex&amp;gt; (u, v) \in E &amp;lt;/tex&amp;gt;&lt;br /&gt;
          '''if''' &amp;lt;tex&amp;gt;d[v] &amp;gt; d[u] + \omega(u, v) &amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''then''' &amp;lt;tex&amp;gt;d[v] \leftarrow d[u] + \omega(u, v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''for''' для каждого ребра &amp;lt;tex&amp;gt; (u, v) \in E &amp;lt;/tex&amp;gt;&lt;br /&gt;
       '''if''' &amp;lt;tex&amp;gt;d[v] &amp;gt; d[u] + \omega(u, v) &amp;lt;/tex&amp;gt;&lt;br /&gt;
          '''then''' '''return''' &amp;lt;tex&amp;gt; \mathit false&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''return''' &amp;lt;tex&amp;gt; \mathit true &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В этом алгоритме используется релаксация, в результате которой &amp;lt;tex&amp;gt;d[v]&amp;lt;/tex&amp;gt; уменьшается до тех пор, пока не станет равным &amp;lt;tex&amp;gt;\delta(s, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;tex&amp;gt;d[v]&amp;lt;/tex&amp;gt; - оценка веса кратчайшего пути из вершины &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в каждую вершину &amp;lt;tex&amp;gt;v \in V&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\delta(s, v)&amp;lt;/tex&amp;gt; - фактический вес кратчайшего пути из  &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=Пусть &amp;lt;tex&amp;gt;G = (V, E) &amp;lt;/tex&amp;gt; — взвешенный ориентированный граф, &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; — стартовая вершина. Тогда после завершения &amp;lt;tex&amp;gt; |V| - 1 &amp;lt;/tex&amp;gt; итераций цикла для всех вершин, достижимых из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, выполняется равенство &amp;lt;tex&amp;gt; d[v] = \delta (s, v) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Рассмотрим произвольную вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, достижимую из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p = \langle v_0,..., v_{k} \rangle &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_0 = s&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;v_{k} = v&amp;lt;/tex&amp;gt; — кратчайший ациклический путь из &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt;. Путь &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; содержит не более &amp;lt;tex&amp;gt; |V| - 1 &amp;lt;/tex&amp;gt; ребер. Поэтому &amp;lt;tex&amp;gt;k \le |V| - 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Докажем следующее утверждение: &lt;br /&gt;
:После &amp;lt;tex&amp;gt;n : (n \le k)&amp;lt;/tex&amp;gt; итераций первого цикла алгоритма, &amp;lt;tex&amp;gt;d[v_n] = \delta(s, v_n) &amp;lt;/tex&amp;gt;&lt;br /&gt;
Воспользуемся индукцией по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
'''База индукции'''&lt;br /&gt;
:Перед первой итерацией утверждение очевидно выполнено: &amp;lt;tex&amp;gt;d[v_0] = d[s] = \delta(s, s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
'''Индукционный переход'''&lt;br /&gt;
:Пусть после &amp;lt;tex&amp;gt;n : (n &amp;lt; k)&amp;lt;/tex&amp;gt; итераций, верно что &amp;lt;tex&amp;gt;d[v_n] = \delta(s, v_n)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;(v_n, v_{n + 1})&amp;lt;/tex&amp;gt; принадлежит кратчайшему пути от &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\delta(s, v_{n+1}) = \delta(s, v_n) + \omega(v_n, v_{n + 1})&amp;lt;/tex&amp;gt;. Во время &amp;lt;tex&amp;gt;l + 1&amp;lt;/tex&amp;gt; итерации релаксируется ребро &amp;lt;tex&amp;gt;(v_n,v_{n+1})&amp;lt;/tex&amp;gt;, следовательно по завершению итерации будет выполнено&lt;br /&gt;
::&amp;lt;tex&amp;gt;d[v_{n+1}] \le d[v_n] + \omega(v_n, v_{n+1}) = \delta(s, v_n) + \omega(v_n, v_{n+1}) = \delta(s, v_{n+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Ясно, что &amp;lt;tex&amp;gt;d[v_{n+1}] \ge \delta(s, v_{n+1}) &amp;lt;/tex&amp;gt;, поэтому верно что после &amp;lt;tex&amp;gt;l + 1&amp;lt;/tex&amp;gt; итерации &amp;lt;tex&amp;gt;d[v_{n+1}] = \delta(s, v_{n + 1})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
:Индукционный переход доказан.&lt;br /&gt;
&lt;br /&gt;
Итак, выполнены равенства &amp;lt;tex&amp;gt;d[v] = d[v_{k}] = \delta (s, v_{k}) = \delta (s, v)&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Пусть &amp;lt;tex&amp;gt;G = (V, E) &amp;lt;/tex&amp;gt; - взвешенный ориентированный граф, &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt; — стартовая вершина. Если граф &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; не содержит отрицательных циклов, достижимых из вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt;, то алгоритм возвращает &amp;lt;tex&amp;gt; true &amp;lt;/tex&amp;gt; и для всех &amp;lt;tex&amp;gt; v \in V \  d[v] = \delta (s, v)&amp;lt;/tex&amp;gt;. Если граф &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; содержит отрицательные циклы, достижимые из вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt;, то алгоритм возвращает &amp;lt;tex&amp;gt; false &amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Пусть граф &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; не содержит отрицательных циклов, достижимых из вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда если вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; достижима из &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt;, то по лемме &amp;lt;tex&amp;gt; d[v] = \delta (s, v)&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; не достижима из &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt; d[v] = \delta (s, v) = \mathcal {1}&amp;lt;/tex&amp;gt; из несуществования пути. &lt;br /&gt;
&lt;br /&gt;
Теперь докажем, что алгоритм вернет значение &amp;lt;tex&amp;gt; true &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
После выполнения алгоритма верно, что для всех &amp;lt;tex&amp;gt; (u, v) \in E, \  d[v] = \delta (s, v) \leqslant \delta (s, u) + \omega (u,v) = d[u] + \omega (u,v)&amp;lt;/tex&amp;gt;, значит ни одна из проверок не вернет значения &amp;lt;tex&amp;gt; false &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть граф &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; содержит отрицательный цикл &amp;lt;tex&amp;gt; c = {v_0,...,v_{k}} &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; v_0 = v_{k} &amp;lt;/tex&amp;gt;, достижимый из вершины &amp;lt;tex&amp;gt; s &amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\sum\limits_{i=1}^{k} {\omega (v_{i-1}, v_{i})} &amp;lt; 0 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Предположим, что алгоритм возвращает &amp;lt;tex&amp;gt; true &amp;lt;/tex&amp;gt;, тогда для &amp;lt;tex&amp;gt; i = 1,...,k &amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt; d[v_{i}] \leqslant d[v_{i-1}] + \omega (v_{i-1}, v_{i}) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Просуммируем эти неравенства по всему циклу: &amp;lt;tex&amp;gt;\sum\limits_{i=1}^{k} {d[v_{i}]} \leqslant \sum\limits_{i=1}^{k} {d[v_{i-1}]} + \sum\limits_{i=1}^{k} {\omega (v_{i-1}, v_{i})} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из того, что &amp;lt;tex&amp;gt; v_0 = v_{k} &amp;lt;/tex&amp;gt; следует, что &amp;lt;tex&amp;gt; \sum\limits^{k}_{i=1} {d[v_{i}]} = \sum \limits_{i=1}^{k} {d[v_{i - 1}]} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Получили, что &amp;lt;tex&amp;gt; \sum \limits_{i=1}^{k} {\omega (v_{i-1}, v_{i})} \ge 0 &amp;lt;/tex&amp;gt;, что противоречит отрицательности цикла &amp;lt;tex&amp;gt; c &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Сложность==&lt;br /&gt;
Инициализация занимает &amp;lt;tex&amp;gt; \Theta (V) &amp;lt;/tex&amp;gt; времени, каждый из &amp;lt;tex&amp;gt; |V| - 1 &amp;lt;/tex&amp;gt; проходов требует &amp;lt;tex&amp;gt; \Theta (E) &amp;lt;/tex&amp;gt; времени, обход по всем ребрам для проверки наличия отрицательного цикла занимает &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt; времени. Значит алгоритм Беллмана-Форда работает за &amp;lt;tex&amp;gt;O(V E)&amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
&lt;br /&gt;
==Нахождение отрицательного цикла==&lt;br /&gt;
Приведенная выше реализация позволяет определить наличие в графе цикла отрицательного веса. Чтобы найти сам цикл, достаточно хранить вершины, из которых производится релаксация. &lt;br /&gt;
&lt;br /&gt;
Если после &amp;lt;tex&amp;gt;|V| - 1&amp;lt;/tex&amp;gt; итерации найдется вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt;, расстояние до которой можно уменьшить, то эта вершина либо лежит на каком-нибудь цикле отрицательного веса, либо достижима из него. Чтобы найти вершину, которая лежит на цикле, можно &amp;lt;tex&amp;gt;|V| - 1&amp;lt;/tex&amp;gt; раз пройти назад по предкам из вершины &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt;. Так как наибольшая длина пути в графе из &amp;lt;tex&amp;gt;|V|&amp;lt;/tex&amp;gt; вершин равна &amp;lt;tex&amp;gt;|V| - 1&amp;lt;/tex&amp;gt;, то полученная вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; будет гарантированно лежать на отрицательном цикле. &lt;br /&gt;
&lt;br /&gt;
Зная, что вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; лежит на цикле отрицательного веса, можно восстанавливать путь по сохраненным вершинам до тех пор, пока не встретится та же вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;. Это обязательно произойдет, так как в цикле отрицательного веса релаксации происходят по кругу.&lt;br /&gt;
&lt;br /&gt;
   '''Neg_Cycle(G, s)'''&lt;br /&gt;
   '''for''' для каждой &amp;lt;tex&amp;gt;v \in V&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; d[v] \leftarrow \mathcal {1} &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; p[v] \leftarrow -1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt;d[s] \leftarrow 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt; i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;|V| - 1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' для каждого ребра &amp;lt;tex&amp;gt; (u, v) \in E &amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d[v] &amp;gt; d[u] + \omega(u, v) &amp;lt;/tex&amp;gt; '''then'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;d[v] \leftarrow d[u] + \omega(u, v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;p[v] \leftarrow u&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' для каждого ребра &amp;lt;tex&amp;gt; (u, v) \in E &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;d[v] &amp;gt; d[u] + \omega(u, v)&amp;lt;/tex&amp;gt; '''then''' &lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt; i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;|V| - 1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;v \leftarrow p[v]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;u \leftarrow v&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''while''' &amp;lt;tex&amp;gt; u \neq p[v]&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;ans.add(v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;v \leftarrow p[v]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;reverse(ans)&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''break'''&lt;br /&gt;
   '''return''' &amp;lt;tex&amp;gt; ans &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн, К. Алгоритмы: построение и анализ / пер. с англ. — изд. 2-е — М.: Издательский дом «Вильямс», 2009. — с.672 — 676. — ISBN 978-5-8459-0857-5.&lt;br /&gt;
* [http://e-maxx.ru/algo/export_ford_bellman Алгоритм Форда-Беллмана]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Кратчайшие пути в графах]]&lt;/div&gt;</summary>
		<author><name>93.175.2.232</name></author>	</entry>

	</feed>