<?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=37.146.177.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=37.146.177.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/37.146.177.232"/>
		<updated>2026-05-20T13:56:12Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4%D0%B0_%D0%B2_%D0%B3%D0%BB%D1%83%D0%B1%D0%B8%D0%BD%D1%83_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D1%86%D0%B8%D0%BA%D0%BB%D0%B0&amp;diff=66125</id>
		<title>Использование обхода в глубину для поиска цикла</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4%D0%B0_%D0%B2_%D0%B3%D0%BB%D1%83%D0%B1%D0%B8%D0%BD%D1%83_%D0%B4%D0%BB%D1%8F_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D1%86%D0%B8%D0%BA%D0%BB%D0%B0&amp;diff=66125"/>
				<updated>2018-06-20T21:41:48Z</updated>
		
		<summary type="html">&lt;p&gt;37.146.177.232: /* Реализация для случая ориентированного графа */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = Дан граф, требуется проверить наличие [[Основные определения теории графов|цикла]] в этом графе.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
&lt;br /&gt;
Будем решать задачу с помощью [[Обход в глубину, цвета вершин|поиска в глубину]].&lt;br /&gt;
&lt;br /&gt;
В случае &amp;lt;b&amp;gt;ориентированного графа&amp;lt;/b&amp;gt; произведём серию обходов. То есть из каждой вершины, в которую мы ещё ни разу не приходили, запустим поиск в глубину, который при входе в вершину будет красить её в серый цвет, а при выходе из нее {{---}} в чёрный. И, если алгоритм пытается пойти в серую вершину, то это означает, что цикл найден.&lt;br /&gt;
&lt;br /&gt;
В случае &amp;lt;b&amp;gt;неориентированного графа&amp;lt;/b&amp;gt;, одно ребро не должно встречаться в [[Основные определения теории графов#def_no_graph_path|цикле]] дважды по определению. Поэтому необходимо дополнительно проверять, что текущее рассматриваемое из вершины ребро не являетя тем ребром, по которому мы пришли в эту вершину.&lt;br /&gt;
&lt;br /&gt;
Заметим, что, если в графе есть вершины с петлями, то алгоритм будет работать корректно, так как при запуске поиска в глубину из такой вершины, найдется ребро, ведущее в нее же, а значит эта петля и будет являться циклом.&lt;br /&gt;
&lt;br /&gt;
Для восстановления самого цикла достаточно при запуске поиска в глубину из очередной вершины добавлять эту вершину в [[Стек|стек]]. Когда поиск в глубину нашел вершину, которая лежит на цикле, будем последовательно вынимать вершины из стека, пока не встретим найденную еще раз. Все вынутые вершины будут лежать на искомом цикле.&lt;br /&gt;
&lt;br /&gt;
Асимптотика поиска цикла совпадает с асимптотикой поиска в глубину {{---}} &amp;lt;tex&amp;gt;O(|V| + |E|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл: Dfs_cycle.png|thumb|200px|right| Момент нахождения цикла: &amp;lt;font color=blue&amp;gt;синие&amp;lt;/font&amp;gt; ребра {{---}} уже пройденные, &amp;lt;font color=red&amp;gt;красное&amp;lt;/font&amp;gt; ребро ведет в серую, уже пройденную, вершину.]]&lt;br /&gt;
&lt;br /&gt;
== Доказательство ==&lt;br /&gt;
&lt;br /&gt;
Пусть дан граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;. Запустим &amp;lt;tex&amp;gt;\mathrm{dfs}(G)&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 &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; v &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; состоящий из одного ребра. И так как оба эти пути не пересекаются, то цикл существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что если в графе &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует цикл, то &amp;lt;tex&amp;gt;\mathrm{dfs}(G)&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; v &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; 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; v &amp;lt;/tex&amp;gt;, то это ребро в серую вершину. Следовательно &amp;lt;tex&amp;gt;\mathrm{dfs}(G)&amp;lt;/tex&amp;gt; нашел цикл.&lt;br /&gt;
&lt;br /&gt;
== Реализация для случая ориентированного графа ==&lt;br /&gt;
 &amp;lt;font color=darkgreen&amp;gt;// color {{---}} массив цветов, изначально все вершины белые &amp;lt;/font&amp;gt; &lt;br /&gt;
 '''func''' dfs(v: '''vertex'''):            &amp;lt;font color=darkgreen&amp;gt; // v {{---}} вершина, в которой мы сейчас находимся &amp;lt;/font&amp;gt;&lt;br /&gt;
     color[v] = &amp;lt;i&amp;gt;grey&amp;lt;/i&amp;gt;             &lt;br /&gt;
     '''for''' (u: vu &amp;lt;tex&amp;gt;\in&amp;lt;/tex&amp;gt; E)&lt;br /&gt;
         '''if''' (color[u] == &amp;lt;i&amp;gt;white&amp;lt;/i&amp;gt;)&lt;br /&gt;
             dfs(u)&lt;br /&gt;
         '''if''' (color[u] == &amp;lt;i&amp;gt;grey&amp;lt;/i&amp;gt;)&lt;br /&gt;
             print()             &amp;lt;font color=darkgreen&amp;gt; // вывод ответа &amp;lt;/font&amp;gt;   &lt;br /&gt;
     color[v] = &amp;lt;i&amp;gt;black&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&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/finding_cycle MAXimal :: algo {{---}} «Проверка графа на ацикличность и нахождение цикла»]&lt;br /&gt;
* [http://shujkova.ru/sites/default/files/algorithm2.pdf Прикладные задачи алгоритма DFS]&lt;br /&gt;
* ''Кормен Т., Лейзерсон Ч., Ривест Р.'' Алгоритмы: построение и анализ.[http://wmate.ru/ebooks/?dl=380&amp;amp;mirror=1] — 2-е изд. — М.: Издательский дом «Вильямс», 2007. — С. 1296.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Обход в глубину]]&lt;/div&gt;</summary>
		<author><name>37.146.177.232</name></author>	</entry>

	</feed>