<?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=91.203.168.223&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=91.203.168.223&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/91.203.168.223"/>
		<updated>2026-05-19T18:46:35Z</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_%22%D0%BF%D0%BE%D0%B4%D0%BD%D1%8F%D1%82%D1%8C-%D0%B2-%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D0%BE%22&amp;diff=28930</id>
		<title>Алгоритм &quot;поднять-в-начало&quot;</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_%22%D0%BF%D0%BE%D0%B4%D0%BD%D1%8F%D1%82%D1%8C-%D0%B2-%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D0%BE%22&amp;diff=28930"/>
				<updated>2013-01-06T14:24:23Z</updated>
		
		<summary type="html">&lt;p&gt;91.203.168.223: /* Операция разгрузки (discharge) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Алгоритм &amp;quot;поднять-в-начало&amp;quot; (relabel-to-front)''' основан на [[Метод проталкивания предпотока|методе проталкивание предпотока]], но из-за тщательного выбора порядка выполнения операций [[Метод проталкивания предпотока#Проталкивание (push)|проталкивания]] и [[Метод проталкивания предпотока#Подъем (relabel)|подъема]], время выполнения данного алгоритма составляет &amp;lt;tex&amp;gt;O(V^{3})&amp;lt;/tex&amp;gt;, что асимптотически не хуже, чем &amp;lt;tex&amp;gt;O(V^{2}E)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Допустимые ребра ==&lt;br /&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; и стоком &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; {{---}} [[Метод проталкивания предпотока#Определения|предпоток]] в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; {{---}} [[Метод проталкивания предпотока#Определения|функция высоты]].&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Допустимое ребро (admissible edge)''' {{---}} ребро &amp;lt;tex&amp;gt;uv&amp;lt;/tex&amp;gt;, у которого &amp;lt;tex&amp;gt;c_{f}(u, v) &amp;gt; 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;h(u) = h(v) + 1&amp;lt;/tex&amp;gt;. В противном случае &amp;lt;tex&amp;gt;uv&amp;lt;/tex&amp;gt; называется '''недопустимым (inadmissible)'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Допустимая сеть (admissible network)''' {{---}} сеть &amp;lt;tex&amp;gt;G_{f, h} = (V, E_{f, h})&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;E_{f, h}&amp;lt;/tex&amp;gt; {{---}} множество допустимых ребер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id = Лемма1&lt;br /&gt;
|about = Допустимая сеть является ациклической&lt;br /&gt;
|statement =&lt;br /&gt;
Допустимая сеть &amp;lt;tex&amp;gt;G_{f, h} = (V, E_{f, h})&amp;lt;/tex&amp;gt; является ациклической.&lt;br /&gt;
|proof =&lt;br /&gt;
Пусть в &amp;lt;tex&amp;gt;G_{f, h}&amp;lt;/tex&amp;gt; существует [[Основные определения теории графов|циклический путь]] &amp;lt;tex&amp;gt;p = \left \langle v_0, v_1, \dots, v_k \right \rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k &amp;gt; 0&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; ~ ~ h(v_{i - 1}) = h(v_{i}) + 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1, 2, \dots, k&amp;lt;/tex&amp;gt;, так как каждое ребро данного пути допустимое. Просуммировав равенства вдоль циклического пути, получаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum \limits_{i = 1}^{k} h(v_{i - 1}) = \sum \limits_{i = 1}^{k} (h(v_{i}) + 1) = \sum \limits_{i = 1}^{k} h(v_{i}) + k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как каждая вершина циклического пути &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; встречается при суммировании по одному разу это значит то, что &amp;lt;tex&amp;gt;k = 0&amp;lt;/tex&amp;gt;, что противоречит первоначальному предположению. Значит, допустимая сеть является ациклической.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id = Лемма2&lt;br /&gt;
|about = Об изменении допустимой цепи с помощью операции проталкивания&lt;br /&gt;
|statement =&lt;br /&gt;
Если вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; переполнена и ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; допустимое, то применяемая операция &amp;lt;tex&amp;gt;push(u, v)&amp;lt;/tex&amp;gt; не создает новые допустимые ребра, но может привести к тому, что ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; станет недопустимым.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; допустимое то, по определению допустимого ребра, из &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; можно протолкнуть поток. Из-за того что &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; {{---}} переполнена, вызываем операцию &amp;lt;tex&amp;gt;push(u, v)&amp;lt;/tex&amp;gt;. В результате выполнения операции может быть создано остаточное ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;. Так ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; допустимое то, &amp;lt;tex&amp;gt;h[v] = h[u] - 1&amp;lt;/tex&amp;gt;, а это значит, что ребро &amp;lt;tex&amp;gt;(v, u)&amp;lt;/tex&amp;gt; не может стать допустимым.&lt;br /&gt;
&lt;br /&gt;
Если выполненная операция &amp;lt;tex&amp;gt;push(u, v)&amp;lt;/tex&amp;gt; является насыщающим проталкиванием, то после ее выполнения &amp;lt;tex&amp;gt;c_{f}(u, v) = 0&amp;lt;/tex&amp;gt; и ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; становится недопустимым.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id = Лемма3&lt;br /&gt;
|about = Об изменении допустимой цепи с помощью операции подъема&lt;br /&gt;
|statement =&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;, то применяется операция &amp;lt;tex&amp;gt;relabel(u)&amp;lt;/tex&amp;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;
|proof =&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; переполнена, то, согласно [[Метод проталкивания предпотока#Лемма2|лемме (2)]], к ней может быть применима либо операция проталкивания, либо операция подъема. А так как не существует допустимых ребер для &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, то протолкнуть поток не возможно, значит, применяется операция &amp;lt;tex&amp;gt;relabel(u)&amp;lt;/tex&amp;gt;. После данного подъема &amp;lt;tex&amp;gt;h[u] = 1 + min \{ h[v]: (u, v) \in E_{f} \}&amp;lt;/tex&amp;gt;. Значит, если &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; {{---}} вершина указанного множества, в которой реализуется минимум, то &amp;lt;tex&amp;gt;(u, v)&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, v)&amp;lt;/tex&amp;gt; допустимо. Тогда &amp;lt;tex&amp;gt;h[v] = h[u] + 1&amp;lt;/tex&amp;gt;, значит, перед подъемом &amp;lt;tex&amp;gt;h[v] &amp;gt; h[u] + 1&amp;lt;/tex&amp;gt;. Но между вершинами, высоты которых отличаются более чем на 1, не существует остаточных сетей. Кроме того, подъем вершины не меняет остаточную сеть. Значит, ребро &amp;lt;tex&amp;gt;(v, u)&amp;lt;/tex&amp;gt; не может находится в допустимой сети, так как оно не принадлежит остаточной сети.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Операция разгрузки (discharge) ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Разгрузка (discharge)''' {{---}} операция, применяемая к переполненной вершине &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;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;
&lt;br /&gt;
Будем хранить для каждой вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; список &amp;lt;tex&amp;gt;N[u]&amp;lt;/tex&amp;gt; (список вершин, смежных с ней). То есть список &amp;lt;tex&amp;gt;N[u]&amp;lt;/tex&amp;gt; содержит каждую вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; такую, что в сети &amp;lt;tex&amp;gt;G = (V, E) ~ (u, v) \in E&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;(v, u) \in E&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
На первую вершину в списке указывает указатель &amp;lt;tex&amp;gt;head[N[u]]&amp;lt;/tex&amp;gt;. Для перехода к следующей вершине в списке за &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;, поддерживается указатель &amp;lt;tex&amp;gt;next[w]&amp;lt;/tex&amp;gt;. Он равен &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;w&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;current[u]&amp;lt;/tex&amp;gt; {{---}} указатель на текущую вершину списка. Изначально &amp;lt;tex&amp;gt;current[u] = head[N[u]]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''discharge'''(u)&lt;br /&gt;
     '''while''' e[u] &amp;gt; 0&lt;br /&gt;
         v = current[u]&lt;br /&gt;
         '''if''' v = null&lt;br /&gt;
             relabel(u)&lt;br /&gt;
             current[u] = head[N[u]]&lt;br /&gt;
         '''else'''&lt;br /&gt;
             '''if''' c(u, v) - f(u, v) &amp;gt; 0 and h[u] = h[v] + 1&lt;br /&gt;
                 push(u, v)&lt;br /&gt;
             '''else'''&lt;br /&gt;
                 current[u] = next[v]&lt;br /&gt;
&lt;br /&gt;
Операция завершится только тогда, когда избыток &amp;lt;tex&amp;gt;e(u)&amp;lt;/tex&amp;gt; станет равным нулю, и ни подъем, ни перемещение указателя &amp;lt;tex&amp;gt;current[u]&amp;lt;/tex&amp;gt; не влияет на значение &amp;lt;tex&amp;gt;e(u)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Докажем то, что когда операция '''discharge''' вызывает операции [[Метод проталкивания предпотока#Проталкивание (push)|push]] и [[Метод проталкивания предпотока#Подъем (relabel)|relable]], эти операции применимы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about = О применимости операции push&lt;br /&gt;
|id = Лемма4&lt;br /&gt;
|statement =&lt;br /&gt;
Когда операция &amp;lt;tex&amp;gt;discharge&amp;lt;/tex&amp;gt; вызывает в операцию &amp;lt;tex&amp;gt;push(u, v)&amp;lt;/tex&amp;gt;, то для пары вершин &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; применима операция проталкивания.&lt;br /&gt;
|proof =&lt;br /&gt;
Проверки операции &amp;lt;tex&amp;gt;discharge&amp;lt;/tex&amp;gt;, сделанные до вызова операции проталкивания, гарантируют то, что операция &amp;lt;tex&amp;gt;push&amp;lt;/tex&amp;gt; будет вызвана только тогда, когда она применима. То есть &amp;lt;tex&amp;gt;e(u) &amp;gt; 0&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;c_{f}(u, v) &amp;gt; 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;h(u) = h(v) + 1&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about = О применимости операции relabel&lt;br /&gt;
|id = Лемма5&lt;br /&gt;
|statement =&lt;br /&gt;
Когда операция &amp;lt;tex&amp;gt;discharge&amp;lt;/tex&amp;gt; вызывает в операцию &amp;lt;tex&amp;gt;relabel(u)&amp;lt;/tex&amp;gt;, то для вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; применим подъем.&lt;br /&gt;
|proof =&lt;br /&gt;
Из [[Алгоритм &amp;quot;поднять-в-начало&amp;quot;#Лемма3|леммы об изменении допустимой цепи (для операции relabel)]] и условия &amp;lt;tex&amp;gt;e(u) &amp;gt; 0&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;discharge(u)&amp;lt;/tex&amp;gt; начинается с головы списка &amp;lt;tex&amp;gt;N[u]&amp;lt;/tex&amp;gt; и оканчивается, когда &amp;lt;tex&amp;gt;current[u] = null&amp;lt;/tex&amp;gt;. Именно тогда вызывается &amp;lt;tex&amp;gt;relabel(u)&amp;lt;/tex&amp;gt; и начинается новый проход. К концу прохода все ребра, выходящие из &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, станут недопустимыми, так как из [[Алгоритм &amp;quot;поднять-в-начало&amp;quot;#Лемма2|леммы об изменении допустимой цепи (для операции push)]] следует, что операции проталкивания не создают допустимых ребер. То есть любое допустимое ребро могло быть создано только в результате выполнения операции подъема. Но вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; не подвергается подъему во время прохода, а любая другая вершина &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, для которой вызывалась операция подъема, во время данного прохода, не имеет после подъема допустимых ребер, что следует из [[Алгоритм &amp;quot;поднять-в-начало&amp;quot;#Лемма3|леммы об изменении допустимой цепи (для операции relabel)]]. Значит, в конце прохода все ребра, выходящие из &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, останутся недопустимыми.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Инициализируем предпоток и высоты, с помощью операции [[Метод проталкивания предпотока#Схема алгоритма|initializePreflow]], список &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} список для хранения всех вершин графа, кроме стока и истока. Проинициализируем указатель &amp;lt;tex&amp;gt;current&amp;lt;/tex&amp;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;
Пройдем по списку &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; разгружая вершины, начиная с первой вершины. И если операция &amp;lt;tex&amp;gt;discharge&amp;lt;/tex&amp;gt; изменила высоту вершины, то перемещаем ее в начало списка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Передвинем указатель на следующую вершину списке &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, если после разгрузки была изменена высота, то берем следующую вершину в новом списке &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
  '''relabelToFront(s, t)'''&lt;br /&gt;
      initializePreflow(s)&lt;br /&gt;
      L = V / {s, t}&lt;br /&gt;
      '''for''' u &amp;lt;tex&amp;gt;\in&amp;lt;/tex&amp;gt; V / {s, t}&lt;br /&gt;
          current[u] = head[N[u]]&lt;br /&gt;
      u = head[L]&lt;br /&gt;
      '''while''' u != null&lt;br /&gt;
          oldHeight = h[u]&lt;br /&gt;
          discharge(u)&lt;br /&gt;
          '''if''' h[u] &amp;gt; oldHeight&lt;br /&gt;
              передвинуть u в начало списка L&lt;br /&gt;
          u = nextVartex[u]&lt;br /&gt;
&lt;br /&gt;
В приведенном псевдокоде предполагается, что для каждой вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; уже создан список &amp;lt;tex&amp;gt;N[u]&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;nextVartex[u]&amp;lt;/tex&amp;gt; возвращает вершину, следующую за &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; в списке &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; {{---}} последняя вершина в списке, то &amp;lt;tex&amp;gt;nextVartex[u] = null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инвариант цикла''': &amp;quot;при каждом выполнении проверки условия вхождения в цикл '''while''', список &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; является топологическим упорядочением вершин допустимой сети &amp;lt;tex&amp;gt;G_{f, h} = (V, E_{f, h})&amp;lt;/tex&amp;gt;, и ни одна вершина, стоящая в списке перед &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, не имеет избыточного потока&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма ==&lt;br /&gt;
Для доказательства корректности алгоритма, то есть чтобы показать что операция &amp;lt;tex&amp;gt;relabelToFront&amp;lt;/tex&amp;gt; вычисляет поток, покажем, что она является реализацией универсального алгоритма [[Метод проталкивания предпотока|проталкивания предпотока]]. Для начала, заметим, что она выполняет операции &amp;lt;tex&amp;gt;push&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;relabel&amp;lt;/tex&amp;gt; только тогда, когда они применимы, следует из [[Алгоритм &amp;quot;поднять-в-начало&amp;quot;#Лемма4|лемм о применимости операций push и relabel]]. Покажем, что когда операция &amp;lt;tex&amp;gt;relabelToFront&amp;lt;/tex&amp;gt; завершится, не применима ни одна основная операция. Для этого подробно рассмотрим операцию &amp;lt;tex&amp;gt;relabelToFront&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
#После вызова &amp;lt;tex&amp;gt;initializePreflow&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;h[s] = |V|&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;h[u] = 0&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;u \in V / {s}&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;|V| \ge 2&amp;lt;/tex&amp;gt;, то ни одно ребро не является допустимым. Значит, &amp;lt;tex&amp;gt;E_{f, h} = \varnothing&amp;lt;/tex&amp;gt; и любой порядок множества &amp;lt;tex&amp;gt;V \setminus \{s, t\}&amp;lt;/tex&amp;gt; является топологическим упорядочением &amp;lt;tex&amp;gt;G_{f, h}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#Проверим, что топологическое упорядочение сохранится при проведении итераций цикла '''while'''. Для начала заметим, что сеть может изменится только из-за операций проталкивания и подъема. Из [[Алгоритм &amp;quot;поднять-в-начало&amp;quot;#Лемма2|леммы об изменении допустимой цепи]] нам известно, что после операции проталкивания новые допустимые ребра не появляются, а это значит, что они могли появится только во время выполнения операции подъема. После того как для вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; применили операцию подъема больше не существует допустимых ребер, входящих в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, но могут быть допустимые ребра, выходящие из нее. Таким образом, перемещая &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; в начало списка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, все допустимые ребра, выходящие из &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, удовлетворяют условию топологического упорядочения.&lt;br /&gt;
#Проверим, что ни одна вершина, предшествующая &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; в списке &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;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;
##Если &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; подверглась подъему, то вершин предшествующих &amp;lt;tex&amp;gt;u'&amp;lt;/tex&amp;gt; на следующей итерации, кроме &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, нет или если высота &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; не изменилась, то там остались те же вершины, что и ранее. Так как &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;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;
##Если высота &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; не поменялась, в процессе разгрузки, то вершины, стоящие в списке &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; перед ней, не получили избыток потока, так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; топологически упорядочен все время в процессе разгрузки, поэтому каждая операция проталкивания продвигает поток только по вершинам дальше по списку. В этом случае ни одна вершина, предшествующая &amp;lt;tex&amp;gt;u'&amp;lt;/tex&amp;gt;, также не имеет избытка потока.&lt;br /&gt;
#После завершения цикла &amp;lt;tex&amp;gt;u = null&amp;lt;/tex&amp;gt;, поэтому избыток всех вершин равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; (инвариант цикла). Значит, ни одна основная операция неприменима.&lt;br /&gt;
&lt;br /&gt;
== Оценка быстродействия ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement =&lt;br /&gt;
Время выполнения операции &amp;lt;tex&amp;gt;relabelToFront&amp;lt;/tex&amp;gt; для любой сети &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt; составляет &amp;lt;tex&amp;gt;O(V^{3})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof =&lt;br /&gt;
Пусть '''фаза''' {{---}} время между двумя последовательными операциями подъема. Так как всего, по [[Метод проталкивания предпотока#Лемма6|лемме (6)]], выполняется &amp;lt;tex&amp;gt;O(V^{2})&amp;lt;/tex&amp;gt; подъемов, значит, в алгоритме всего &amp;lt;tex&amp;gt;O(V^{2})&amp;lt;/tex&amp;gt; фаз.&lt;br /&gt;
&lt;br /&gt;
Если операция &amp;lt;tex&amp;gt;discharge&amp;lt;/tex&amp;gt; не выполняет подъем, то следующий ее вызов происходит дальше по списку &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;(&amp;lt;/tex&amp;gt;длина &amp;lt;tex&amp;gt;L&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;discharge&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, цикл '''while''' процедуры &amp;lt;tex&amp;gt;relabelToFront&amp;lt;/tex&amp;gt; выполняет работу (без учета операций вызываемых в &amp;lt;tex&amp;gt;discharge&amp;lt;/tex&amp;gt;), за &amp;lt;tex&amp;gt;O(V^{3})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Оценим работу выполнения внутри операции &amp;lt;tex&amp;gt;discharge&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
#Обновление указателя &amp;lt;tex&amp;gt;current[u]&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;O(deg(u))&amp;lt;/tex&amp;gt; в том случае, когда вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; подвергается подъему. Значит, для всех вершин время составляет &amp;lt;tex&amp;gt;O(V deg(u))&amp;lt;/tex&amp;gt;. Следовательно, согласно [[Лемма о рукопожатиях|лемме о рукопожатиях]], время равно &amp;lt;tex&amp;gt;O(VE)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#Пусть &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; {{---}} произвольная вершина сети. Она может быть поднята не более &amp;lt;tex&amp;gt;O(V)&amp;lt;/tex&amp;gt; раз, время каждого подъема &amp;lt;tex&amp;gt;O(deg(u))&amp;lt;/tex&amp;gt;. Значит, время всех подъемов ограничивается &amp;lt;tex&amp;gt;O(VE)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#Из [[Метод проталкивания предпотока#Лемма8|леммы (8)]] следует, что количество насыщающих проталкиваний составляет &amp;lt;tex&amp;gt;O(VE)&amp;lt;/tex&amp;gt;. Ненасыщающее проталкивание уменьшает избыток до &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, после чего разрядка останавливается. Следовательно, ненасыщающих проталкиваний не больше, чем вызовов &amp;lt;tex&amp;gt;discharge&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;O(V^{3})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, время выполнения операции &amp;lt;tex&amp;gt;relabelToFront&amp;lt;/tex&amp;gt; составляет &amp;lt;tex&amp;gt;O(V^{3} + VE)&amp;lt;/tex&amp;gt;, что эквивалентно &amp;lt;tex&amp;gt;O(V^{3})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. — 2-е изд. — М.: Издательский дом «Вильямс», 2011. — С. 774—785.&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/Алгоритм_проталкивания_предпотока Алгоритм проталкивания предпотока — Википедия]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Задача о максимальном потоке]]&lt;/div&gt;</summary>
		<author><name>91.203.168.223</name></author>	</entry>

	</feed>