<?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=188.162.64.130&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=188.162.64.130&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/188.162.64.130"/>
		<updated>2026-06-08T19:36:31Z</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%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%B0_%D0%B2_%D0%B0%D1%86%D0%B8%D0%BA%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D1%81%D0%B5%D1%82%D0%B8&amp;diff=71051</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%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%B0_%D0%B2_%D0%B0%D1%86%D0%B8%D0%BA%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D1%81%D0%B5%D1%82%D0%B8&amp;diff=71051"/>
				<updated>2019-04-17T21:33:43Z</updated>
		
		<summary type="html">&lt;p&gt;188.162.64.130: /* Удаляющий обход */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Жадный алгоритм==&lt;br /&gt;
Идея заключается в том, чтобы по одному находить пути из [[Определение_сети,_потока|истока]] &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;s&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, если из &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;c(u, v)&amp;gt;0&amp;lt;/tex&amp;gt; поэтому, насыщая рёбра, мы хотя бы единожды достигнем стока &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, следовательно блокирующий поток всегда найдётся.&lt;br /&gt;
&lt;br /&gt;
Используя &amp;lt;tex&amp;gt;dfs&amp;lt;/tex&amp;gt;, каждый путь находится за &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; — число рёбер в графе. Поскольку каждый путь насыщает как минимум одно ребро, всего будет &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt; путей. Итого общая асимптотика составляет &amp;lt;tex&amp;gt;O(E^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Удаляющий обход==&lt;br /&gt;
Аналогично предыдущей идее, однако будем удалять в процессе обхода в глубину из графа все рёбра, вдоль которых не получится дойти до стока &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Это очень легко реализовать: достаточно удалять ребро после того, как мы просмотрели его в обходе в глубину (кроме того случая, когда мы прошли вдоль ребра и нашли путь до стока). С точки зрения реализации, надо просто поддерживать в списке смежности каждой вершины указатель на первое не удалённое ребро, и увеличивать этот указатель в цикле внутри обхода в глубину. Корректность при этом сохраняется согласно предыдущему пункту. &lt;br /&gt;
&lt;br /&gt;
  '''int''' dfs('''int''' &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, '''int''' flow) &lt;br /&gt;
    '''if''' (flow == 0) &lt;br /&gt;
      '''return''' 0&lt;br /&gt;
    '''if''' (&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; == &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''return''' flow&lt;br /&gt;
    '''for''' (&amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; = ptr[&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;] '''to''' n)&lt;br /&gt;
      '''if''' (&amp;lt;tex&amp;gt;vu \in E&amp;lt;/tex&amp;gt;)&lt;br /&gt;
        pushed = dfs(&amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, min(flow, c(&amp;lt;tex&amp;gt;vu&amp;lt;/tex&amp;gt;) - f(&amp;lt;tex&amp;gt;vu&amp;lt;/tex&amp;gt;)))&lt;br /&gt;
        f(&amp;lt;tex&amp;gt;vu&amp;lt;/tex&amp;gt;) += pushed&lt;br /&gt;
        f(&amp;lt;tex&amp;gt;uv&amp;lt;/tex&amp;gt;) -= pushed&lt;br /&gt;
        '''return''' pushed&lt;br /&gt;
      ptr[&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;]++&lt;br /&gt;
    '''return''' 0&lt;br /&gt;
&lt;br /&gt;
  '''main'''()&lt;br /&gt;
    '''...'''&lt;br /&gt;
    flow = 0&lt;br /&gt;
    '''for''' ('''int''' i = 1 '''to''' n)&lt;br /&gt;
      ptr[i] = 0&lt;br /&gt;
    '''do'''&lt;br /&gt;
      pushed = dfs(&amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\infty&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      flow += pushed&lt;br /&gt;
    '''while''' (pushed &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если обход в глубину достигает стока, насыщается как минимум одно ребро, иначе как минимум один указатель продвигается вперед. Значит один запуск обхода в глубину работает за &amp;lt;tex&amp;gt;O(V + K)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; — число вершин в графе, а &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt; — число продвижения указателей. Ввиду того, что всего запусков обхода в глубину в рамках поиска одного [[Блокирующий поток|блокирующего потока]] будет &amp;lt;tex&amp;gt;O(P)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — число рёбер, насыщенных этим блокирующим потоком, то весь алгоритм поиска блокирующего потока отработает за &amp;lt;tex&amp;gt;O(PV + \sum\limits_i{K_i})&amp;lt;/tex&amp;gt;, что, учитывая, что все указатели в сумме прошли расстояние &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt;, дает асимптотику &amp;lt;tex&amp;gt;O(PV + E)&amp;lt;/tex&amp;gt;. В худшем случае, когда блокирующий поток насыщает все рёбра, асимптотика получается &amp;lt;tex&amp;gt;O(VE)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Замечание:&amp;lt;/b&amp;gt; Если в [[Схема алгоритма Диница|алгоритме Диница]] искать блокирующий поток удаляющим обходом, то его эффективность составит &amp;lt;tex&amp;gt;O(V^2E)&amp;lt;/tex&amp;gt;, что уже лучше эффективности [[Алоритм Эдмондса-Карпа|алгоритма Эдмондса-Карпа]] &amp;lt;tex&amp;gt;O(VE^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Малхотры — Кумара — Махешвари==&lt;br /&gt;
===Идея===&lt;br /&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;p&amp;lt;/tex&amp;gt; из истока в сток, проходящий через эту вершину. При этом если [[Дополняющая сеть, дополняющий путь|остаточная пропускная способность]] ребра равна нулю, то это ребро удаляется. Также, удаляются все вершины, у которых не остаётся ни одного входящего и/или ни одного выходящего ребра. При удалении вершины все смежные рёбра удаляются.&lt;br /&gt;
&lt;br /&gt;
===Подробное описание===&lt;br /&gt;
* Для каждой вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; вычислим входящий и исходящий потенциал: &amp;lt;tex&amp;gt;p_{in}=\sum \limits_{u} c(u, v)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_{out}=\sum \limits_{u} c(v, u)&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;p_{in}(s)=\infty&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_{out}(t)=\infty&amp;lt;/tex&amp;gt;. Определим потенциал или пропускную способность вершины в [[Определение сети, потока|сети]] &amp;lt;tex&amp;gt;p(v)=min(p_{in}(v), p_{out}(v))&amp;lt;/tex&amp;gt;. Таким образом, потенциал вершины определяет максимально возможное количество потока, который может через неё проходить. Ясно, что через вершины с &amp;lt;tex&amp;gt;p(v)=0&amp;lt;/tex&amp;gt; поток проходить не может. Следовательно, их можно удалить из [[Дополняющая сеть, дополняющий путь|вспомогательной сети]]. Удалим эти вершины и дуги, им инцидентные, обновив должным образом потенциалы вершин, смежных с удалёнными. Если в результате появятся новые вершины с &amp;lt;tex&amp;gt;p(v)=0&amp;lt;/tex&amp;gt;, удалим рекурсивно и их. В результате во вспомогательной сети останутся только вершины с &amp;lt;tex&amp;gt;p(v)\ne0&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;k&amp;lt;/tex&amp;gt;-ому слою и &amp;lt;tex&amp;gt;p(v)=min (p(w), w \in L_k)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L_k&amp;lt;/tex&amp;gt;  —  &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-й слой. Протолкнем &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt; единиц потока из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в смежные с ней вершины по исходящим дугам с [[Дополняющая сеть, дополняющий путь | остаточной пропускной способностью]] &amp;lt;tex&amp;gt;c_f \ne 0&amp;lt;/tex&amp;gt;. Попутно будем переносить проталкиваемый поток в исходную сеть, а также корректировать потенциалы вершин, отправляющих и принимающих избыток потока. В результате, весь (в виду минимальности потенциала вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;) проталкиваемый поток соберется в вершинах &amp;lt;tex&amp;gt;(k+1)&amp;lt;/tex&amp;gt;-го слоя. &lt;br /&gt;
&lt;br /&gt;
* Повторим процесс отправки потока из вершин &amp;lt;tex&amp;gt;(k+1)&amp;lt;/tex&amp;gt;-го слоя, содержащих избыток потока, в смежные им вершины &amp;lt;tex&amp;gt;(k+2)&amp;lt;/tex&amp;gt;-го слоя. И так до тех пор, пока весь поток не соберется в последнем слое, в котором содержится только сток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, ибо все остальные вершины, ранее ему принадлежащие, были удалены, поскольку их потенциалы нулевые. Следовательно, весь поток величины &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt;, отправленный из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt; - минимальный полностью соберется в &amp;lt;tex&amp;gt;t&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;(k-1)&amp;lt;/tex&amp;gt;-го слоя, затем &amp;lt;tex&amp;gt;(k-2)&amp;lt;/tex&amp;gt;-го. И так до тех пор, пока весь поток величины &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt;, отправленный в вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt; - минимальный, не соберется в истоке &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Таким образом, поток и во вспомогательной и в основной сети увеличится на величину &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 MPM algorithm(&amp;lt;tex&amp;gt;s, t&amp;lt;/tex&amp;gt;)&lt;br /&gt;
 {&lt;br /&gt;
    foreach &amp;lt;tex&amp;gt;(uv) \in E&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;f(uv) \leftarrow 0 &amp;lt;/tex&amp;gt;;&lt;br /&gt;
    Вычисляем остаточную сеть &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;;&lt;br /&gt;
    Найдём вспомогательный граф &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;;&lt;br /&gt;
    while (&amp;lt;tex&amp;gt;t \in L&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    {&lt;br /&gt;
      while (&amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; достижима из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;L&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;g&amp;lt;/tex&amp;gt;;&lt;br /&gt;
        проталкиваем &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; единиц потока из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&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; в &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;;&lt;br /&gt;
        изменяем &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;;&lt;br /&gt;
      }&lt;br /&gt;
      вычисляем новый вспомогательный граф &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;R&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;O(K + E_i)&amp;lt;/tex&amp;gt; действий, где &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt; соответствует числу рёбер, для которых остаточная пропускная способность уменьшилась, но осталась положительной, а &amp;lt;tex&amp;gt;E_i&amp;lt;/tex&amp;gt; — числу удалённых рёбер. Таким образом, для поиска блокирующего потока будет выполнено &amp;lt;tex&amp;gt;\sum\limits_i{O(K+E_i)} = O(K^2)&amp;lt;/tex&amp;gt; действий.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Блокирующий поток]]&lt;br /&gt;
* [[Схема алгоритма Диница]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://e-maxx.ru/algo/dinic  MAXimal :: algo :: Алгоритм Диница]&lt;br /&gt;
*[http://www.facweb.iitkgp.ernet.in/~arijit/courses/autumn2006/cs60001/lec-flow-4.pdf The MPM Algorithm]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BB%D1%85%D0%BE%D1%82%D1%80%D1%8B_%E2%80%94_%D0%9A%D1%83%D0%BC%D0%B0%D1%80%D0%B0_%E2%80%94_%D0%9C%D0%B0%D1%85%D0%B5%D1%88%D0%B2%D0%B0%D1%80%D0%B8 Алгоритм Малхотры — Кумара — Махешвари]&lt;br /&gt;
*[http://eprints.utas.edu.au/160/1/iplFlow.pdf Оригинальная публикация алгоритма Малхотры — Кумара — Махешвари.]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория:Задача о максимальном потоке]]&lt;/div&gt;</summary>
		<author><name>188.162.64.130</name></author>	</entry>

	<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%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%B0_%D0%B2_%D0%B0%D1%86%D0%B8%D0%BA%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D1%81%D0%B5%D1%82%D0%B8&amp;diff=71041</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%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE_%D0%BF%D0%BE%D1%82%D0%BE%D0%BA%D0%B0_%D0%B2_%D0%B0%D1%86%D0%B8%D0%BA%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D1%81%D0%B5%D1%82%D0%B8&amp;diff=71041"/>
				<updated>2019-04-17T20:25:58Z</updated>
		
		<summary type="html">&lt;p&gt;188.162.64.130: /* Удаляющий обход */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Жадный алгоритм==&lt;br /&gt;
Идея заключается в том, чтобы по одному находить пути из [[Определение_сети,_потока|истока]] &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;s&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, если из &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;c(u, v)&amp;gt;0&amp;lt;/tex&amp;gt; поэтому, насыщая рёбра, мы хотя бы единожды достигнем стока &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, следовательно блокирующий поток всегда найдётся.&lt;br /&gt;
&lt;br /&gt;
Используя &amp;lt;tex&amp;gt;dfs&amp;lt;/tex&amp;gt;, каждый путь находится за &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; — число рёбер в графе. Поскольку каждый путь насыщает как минимум одно ребро, всего будет &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt; путей. Итого общая асимптотика составляет &amp;lt;tex&amp;gt;O(E^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Удаляющий обход==&lt;br /&gt;
Аналогично предыдущей идее, однако будем удалять в процессе обхода в глубину из графа все рёбра, вдоль которых не получится дойти до стока &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Это очень легко реализовать: достаточно удалять ребро после того, как мы просмотрели его в обходе в глубину (кроме того случая, когда мы прошли вдоль ребра и нашли путь до стока). С точки зрения реализации, надо просто поддерживать в списке смежности каждой вершины указатель на первое не удалённое ребро, и увеличивать этот указатель в цикле внутри обхода в глубину. Корректность при этом сохраняется согласно предыдущему пункту. &lt;br /&gt;
&lt;br /&gt;
  '''int''' dfs('''int''' &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, '''int''' flow) &lt;br /&gt;
    '''if''' (flow == 0) &lt;br /&gt;
      '''return''' 0&lt;br /&gt;
    '''if''' (&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; == &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''return''' flow&lt;br /&gt;
    '''for''' (&amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; = ptr[&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;] '''to''' n)&lt;br /&gt;
      ptr[&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;]++&lt;br /&gt;
      '''if''' (&amp;lt;tex&amp;gt;vu \in E&amp;lt;/tex&amp;gt;)&lt;br /&gt;
        pushed = dfs(&amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, min(flow, c(&amp;lt;tex&amp;gt;vu&amp;lt;/tex&amp;gt;) - f(&amp;lt;tex&amp;gt;vu&amp;lt;/tex&amp;gt;)))&lt;br /&gt;
        f(&amp;lt;tex&amp;gt;vu&amp;lt;/tex&amp;gt;) += pushed&lt;br /&gt;
        f(&amp;lt;tex&amp;gt;uv&amp;lt;/tex&amp;gt;) -= pushed&lt;br /&gt;
        '''return''' pushed&lt;br /&gt;
    '''return''' 0&lt;br /&gt;
&lt;br /&gt;
  '''main'''()&lt;br /&gt;
    '''...'''&lt;br /&gt;
    flow = 0&lt;br /&gt;
    '''for''' ('''int''' i = 1 '''to''' n)&lt;br /&gt;
      ptr[i] = 0&lt;br /&gt;
    '''do'''&lt;br /&gt;
      pushed = dfs(&amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\infty&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      flow += pushed&lt;br /&gt;
    '''while''' (pushed &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если обход в глубину достигает стока, насыщается как минимум одно ребро, иначе как минимум один указатель продвигается вперед. Значит один запуск обхода в глубину работает за &amp;lt;tex&amp;gt;O(V + K)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; — число вершин в графе, а &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt; — число продвижения указателей. Ввиду того, что всего запусков обхода в глубину в рамках поиска одного [[Блокирующий поток|блокирующего потока]] будет &amp;lt;tex&amp;gt;O(P)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — число рёбер, насыщенных этим блокирующим потоком, то весь алгоритм поиска блокирующего потока отработает за &amp;lt;tex&amp;gt;O(PV + \sum\limits_i{K_i})&amp;lt;/tex&amp;gt;, что, учитывая, что все указатели в сумме прошли расстояние &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt;, дает асимптотику &amp;lt;tex&amp;gt;O(PV + E)&amp;lt;/tex&amp;gt;. В худшем случае, когда блокирующий поток насыщает все рёбра, асимптотика получается &amp;lt;tex&amp;gt;O(VE)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Замечание:&amp;lt;/b&amp;gt; Если в [[Схема алгоритма Диница|алгоритме Диница]] искать блокирующий поток удаляющим обходом, то его эффективность составит &amp;lt;tex&amp;gt;O(V^2E)&amp;lt;/tex&amp;gt;, что уже лучше эффективности [[Алоритм Эдмондса-Карпа|алгоритма Эдмондса-Карпа]] &amp;lt;tex&amp;gt;O(VE^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Малхотры — Кумара — Махешвари==&lt;br /&gt;
===Идея===&lt;br /&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;p&amp;lt;/tex&amp;gt; из истока в сток, проходящий через эту вершину. При этом если [[Дополняющая сеть, дополняющий путь|остаточная пропускная способность]] ребра равна нулю, то это ребро удаляется. Также, удаляются все вершины, у которых не остаётся ни одного входящего и/или ни одного выходящего ребра. При удалении вершины все смежные рёбра удаляются.&lt;br /&gt;
&lt;br /&gt;
===Подробное описание===&lt;br /&gt;
* Для каждой вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; вычислим входящий и исходящий потенциал: &amp;lt;tex&amp;gt;p_{in}=\sum \limits_{u} c(u, v)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_{out}=\sum \limits_{u} c(v, u)&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;p_{in}(s)=\infty&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_{out}(t)=\infty&amp;lt;/tex&amp;gt;. Определим потенциал или пропускную способность вершины в [[Определение сети, потока|сети]] &amp;lt;tex&amp;gt;p(v)=min(p_{in}(v), p_{out}(v))&amp;lt;/tex&amp;gt;. Таким образом, потенциал вершины определяет максимально возможное количество потока, который может через неё проходить. Ясно, что через вершины с &amp;lt;tex&amp;gt;p(v)=0&amp;lt;/tex&amp;gt; поток проходить не может. Следовательно, их можно удалить из [[Дополняющая сеть, дополняющий путь|вспомогательной сети]]. Удалим эти вершины и дуги, им инцидентные, обновив должным образом потенциалы вершин, смежных с удалёнными. Если в результате появятся новые вершины с &amp;lt;tex&amp;gt;p(v)=0&amp;lt;/tex&amp;gt;, удалим рекурсивно и их. В результате во вспомогательной сети останутся только вершины с &amp;lt;tex&amp;gt;p(v)\ne0&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;k&amp;lt;/tex&amp;gt;-ому слою и &amp;lt;tex&amp;gt;p(v)=min (p(w), w \in L_k)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L_k&amp;lt;/tex&amp;gt;  —  &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-й слой. Протолкнем &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt; единиц потока из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в смежные с ней вершины по исходящим дугам с [[Дополняющая сеть, дополняющий путь | остаточной пропускной способностью]] &amp;lt;tex&amp;gt;c_f \ne 0&amp;lt;/tex&amp;gt;. Попутно будем переносить проталкиваемый поток в исходную сеть, а также корректировать потенциалы вершин, отправляющих и принимающих избыток потока. В результате, весь (в виду минимальности потенциала вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;) проталкиваемый поток соберется в вершинах &amp;lt;tex&amp;gt;(k+1)&amp;lt;/tex&amp;gt;-го слоя. &lt;br /&gt;
&lt;br /&gt;
* Повторим процесс отправки потока из вершин &amp;lt;tex&amp;gt;(k+1)&amp;lt;/tex&amp;gt;-го слоя, содержащих избыток потока, в смежные им вершины &amp;lt;tex&amp;gt;(k+2)&amp;lt;/tex&amp;gt;-го слоя. И так до тех пор, пока весь поток не соберется в последнем слое, в котором содержится только сток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, ибо все остальные вершины, ранее ему принадлежащие, были удалены, поскольку их потенциалы нулевые. Следовательно, весь поток величины &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt;, отправленный из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt; - минимальный полностью соберется в &amp;lt;tex&amp;gt;t&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;(k-1)&amp;lt;/tex&amp;gt;-го слоя, затем &amp;lt;tex&amp;gt;(k-2)&amp;lt;/tex&amp;gt;-го. И так до тех пор, пока весь поток величины &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt;, отправленный в вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p(v)&amp;lt;/tex&amp;gt; - минимальный, не соберется в истоке &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Таким образом, поток и во вспомогательной и в основной сети увеличится на величину &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 MPM algorithm(&amp;lt;tex&amp;gt;s, t&amp;lt;/tex&amp;gt;)&lt;br /&gt;
 {&lt;br /&gt;
    foreach &amp;lt;tex&amp;gt;(uv) \in E&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;f(uv) \leftarrow 0 &amp;lt;/tex&amp;gt;;&lt;br /&gt;
    Вычисляем остаточную сеть &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;;&lt;br /&gt;
    Найдём вспомогательный граф &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;;&lt;br /&gt;
    while (&amp;lt;tex&amp;gt;t \in L&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    {&lt;br /&gt;
      while (&amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; достижима из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;L&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;g&amp;lt;/tex&amp;gt;;&lt;br /&gt;
        проталкиваем &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; единиц потока из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&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; в &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;;&lt;br /&gt;
        изменяем &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;;&lt;br /&gt;
      }&lt;br /&gt;
      вычисляем новый вспомогательный граф &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;R&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;O(K + E_i)&amp;lt;/tex&amp;gt; действий, где &amp;lt;tex&amp;gt;K&amp;lt;/tex&amp;gt; соответствует числу рёбер, для которых остаточная пропускная способность уменьшилась, но осталась положительной, а &amp;lt;tex&amp;gt;E_i&amp;lt;/tex&amp;gt; — числу удалённых рёбер. Таким образом, для поиска блокирующего потока будет выполнено &amp;lt;tex&amp;gt;\sum\limits_i{O(K+E_i)} = O(K^2)&amp;lt;/tex&amp;gt; действий.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Блокирующий поток]]&lt;br /&gt;
* [[Схема алгоритма Диница]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://e-maxx.ru/algo/dinic  MAXimal :: algo :: Алгоритм Диница]&lt;br /&gt;
*[http://www.facweb.iitkgp.ernet.in/~arijit/courses/autumn2006/cs60001/lec-flow-4.pdf The MPM Algorithm]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BB%D1%85%D0%BE%D1%82%D1%80%D1%8B_%E2%80%94_%D0%9A%D1%83%D0%BC%D0%B0%D1%80%D0%B0_%E2%80%94_%D0%9C%D0%B0%D1%85%D0%B5%D1%88%D0%B2%D0%B0%D1%80%D0%B8 Алгоритм Малхотры — Кумара — Махешвари]&lt;br /&gt;
*[http://eprints.utas.edu.au/160/1/iplFlow.pdf Оригинальная публикация алгоритма Малхотры — Кумара — Махешвари.]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория:Задача о максимальном потоке]]&lt;/div&gt;</summary>
		<author><name>188.162.64.130</name></author>	</entry>

	</feed>