34. Эйлеровы циклы.
Сначала определения.
Эйлеров путь -- путь в графе, который проходит по каждому ребру графа ровно один раз.
Эйлеров цикл -- замкнутый эйлеров путь.
Существует простой способ определить, есть ли в данном графе эйлеров цикл или эйлеров путь. Для неориентированного графа назовём степенью вершины количество инцидентных ей рёбер (т.е. сколько рёбер с ней связано). Если в связном графе степени всех вершин чётны, то в нём есть эйлеров цикл, если есть ровно две вершины с нечётными степенями -- в графе существует эйлеров путь, который начинается и заканчивается в этих двух вершинах. Для ориентированного графа для вершин определяются полустепени входа и полустепени выхода (количество вершин, входящих и выходящих в данную вершину соответственно) и утверждается, что эйлеров цикл существует, если для каждой вершины полустепень входа совпадает с полустепенью выхода (это, конечно, более сильное утверждение, чем просто чётность степени).
Существует несколько алгоритмов построения эйлерова цикла (если известно, что он существует).
Алгоритм Флёри.
Мост -- ребро, при удалении которого из графа в нём увеличивается количество компонент связности.
Код
0. Выбрать произвольную вершину curr.
1. Если в графе есть ребро (curr, i), не являющееся мостом, выполнить:
1а. вывести его в ответ,
1б. удалить его из графа,
1в. присвоить curr = i и снова перейти к шагу 1.
2. Если в графе есть ребро (curr, i), являющееся мостом, выполнить:
2а. вывести его в ответ,
2б. удалить его из графа,
2в. присвоить curr = i и перейти к шагу 1.
3. Если из вершины curr нет ребёр, завершить выполнение алгоритма.
Алгоритм со стеком. Используется стек, в который кладутся рёбра графа.
Код
0. Выбрать произвольную вершину curr.
1. Если в графе есть ребро (curr, i), выполнить:
1а. удалить его из графа,
1б. присвоить curr = i,
1в. push(curr, i) и перейти к шагу 1.
2. Если в графе нет рёбер из вершины curr, выполнить:
2а. если стек пуст, выход.
2б. выполнить pop(), если (x, y) -- полученное из стека ребро, то присвоить curr = x.
2в. вывести ребро (x, y).
2г. перейти к шагу 1.