<?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=2.92.228.32&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=2.92.228.32&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/2.92.228.32"/>
		<updated>2026-05-24T09:02:48Z</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=74089</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=74089"/>
				<updated>2020-05-02T13:36:47Z</updated>
		
		<summary type="html">&lt;p&gt;2.92.228.32: /* Нахождение отрицательного цикла */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition=Для заданного взвешенного [[Основные определения: граф, ребро, вершина, степень, петля, путь, цикл|графа]] &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;
==Введение==&lt;br /&gt;
Количество путей длины &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; рёбер можно найти с помощью метода [[Динамическое_программирование|динамического программирования]]. &amp;lt;br&amp;gt;&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;d[k][u]&amp;lt;/tex&amp;gt; {{---}} количество путей длины &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; рёбер, заканчивающихся в вершине &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;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;
&lt;br /&gt;
Аналогично посчитаем пути кратчайшей длины. Пусть &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} стартовая вершина. Тогда &amp;lt;tex&amp;gt; d[k][u] = \min\limits_{v : vu \; \in E}(d[k-1][v] \: + \: \omega(u, v))&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;
|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''' k = 0 '''to''' &amp;lt;tex&amp;gt;|V| - 2&amp;lt;/tex&amp;gt;                                           &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// вершины нумеруются с единицы&amp;lt;/font&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, v) \in E &amp;lt;/tex&amp;gt;&lt;br /&gt;
           d[k + 1][v] = min(d[k + 1][v], d[k][u] + &amp;lt;tex&amp;gt;\omega(u, v)&amp;lt;/tex&amp;gt;)     &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// &amp;lt;tex&amp;gt;\omega(u, v)&amp;lt;/tex&amp;gt; {{---}} вес ребра uv&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также релаксацию можно свести к одномерному случаю, если не хранить длину пути в рёбрах. Одномерный массив будем обозначать &amp;lt;tex&amp;gt;d'&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;d'[u] = \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;\mathrm{for}&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;
: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;
 '''bool''' fordBellman(s)''':'''&lt;br /&gt;
     '''for''' &amp;lt;tex&amp;gt;v \in V&amp;lt;/tex&amp;gt;&lt;br /&gt;
         d[v] = &amp;lt;tex&amp;gt;\mathcal {1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
     d[s] = 0&lt;br /&gt;
     '''for''' i = 0 '''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''' d[v] &amp;gt; d[u] + &amp;lt;tex&amp;gt;\omega(u, v)&amp;lt;/tex&amp;gt;     &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// &amp;lt;tex&amp;gt;\omega(u, v)&amp;lt;/tex&amp;gt; {{---}} вес ребра uv&amp;lt;/font&amp;gt;&lt;br /&gt;
                 d[v] = d[u] + &amp;lt;tex&amp;gt;\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''' d[v] &amp;gt; d[u] + &amp;lt;tex&amp;gt;\omega(u, v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''return''' ''false''&lt;br /&gt;
     '''return''' ''true''&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 \leqslant |V| - 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Докажем следующее утверждение: &lt;br /&gt;
:После &amp;lt;tex&amp;gt;n : (n \leqslant 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}] \leqslant 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}] \geqslant \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})} \geqslant 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;
  '''int[]''' negativeCycle(s)''':'''&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;v \in V&amp;lt;/tex&amp;gt;&lt;br /&gt;
          d[v] = &amp;lt;tex&amp;gt;\mathcal {1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
          p[v] = -1&lt;br /&gt;
      d[s] = 0&lt;br /&gt;
      '''for''' i = 1 '''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''' d[v] &amp;gt; d[u] + &amp;lt;tex&amp;gt;\omega(u, v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
                  d[v] = d[u] + &amp;lt;tex&amp;gt;\omega(u, v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
                  p[v] = u&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt; (u, v) \in E &amp;lt;/tex&amp;gt;&lt;br /&gt;
          '''if''' d[v] &amp;gt; d[u] + &amp;lt;tex&amp;gt;\omega(u, v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
              '''for''' i = 0 '''to''' &amp;lt;tex&amp;gt;|V| - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
                  v = p[v]&lt;br /&gt;
              u = v&lt;br /&gt;
              '''while''' u != p[v]&lt;br /&gt;
                  ans.add(v)            &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// добавим вершину к ответу&amp;lt;/font&amp;gt;&lt;br /&gt;
                  v = p[v]&lt;br /&gt;
              reverse(ans)&lt;br /&gt;
              '''break'''&lt;br /&gt;
    '''return''' ans&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд — М.: Издательский дом «Вильямс», 2009. — ISBN 978-5-8459-0857-5.&lt;br /&gt;
* [http://e-maxx.ru/algo/ford_bellman MAXimal :: algo :: Алгоритм Форда-Беллмана]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Кратчайшие пути в графах]]&lt;/div&gt;</summary>
		<author><name>2.92.228.32</name></author>	</entry>

	</feed>