Поиск в глубину: сильная связность, эйлеровость (15 января 2021)
- Хранение графа
- Если удалять рёбра? vector<set<int>>
- Если плотный граф V = 10 000? vector<bitset>
- Если хотим минимизировать память? sizeof(vector<int>) = 24, мультисписок
- Кодим dfs
- Восстановление пути на обратном ходу рекурсии
- Инкапсуляция графа, struct
- Локальный функции, function
- Рёбра − list initialization
- [20 минут] Компоненты сильной связности
- Тривиальный алгоритм поиска за O(kE)
- Алгоритм поиска за O(V+E) двумя dfs (topsort + красим по обратным рёбрам)
- Доказательство корректности (любая достижимая по обратным рёбрам другая компонента уже покрашена)
- Конденсация сс. Определение, построение.
- [20 минут] Эйлеровость
- Критерий эйлеровости для ор и неор
- Доказательство и элементарный алгоритм поиска пути:
выделим цикл жадным циклом for (идём вглубь до упора), по индукции сделаем из каждой компоненты оставшихся рёбер Эйлеровы цикл, склеим.
- Алгоритм поиска для орграфа за O(V+E) одним dfs (
result.push_back(e);
на выходе из dfs)
- Алгоритм поиска для неорграфа отличается тем, что после прохода по ребру нужно удалить парное пройденному.
Удаляем лениво: isdeleted[edge.index] = true;
- Картинки с примерами (почему важен цикл while, почему важно удалять ребро)