- •Алгоритмы на графах
- •3.1. Представление графа в памяти компьютера
- •3.2. Поиск в графе
- •3.2.1. Поиск в глубину
- •3.2.2. Поиск в ширину
- •3.3. Деревья
- •3.3.1. Основные понятия. Стягивающие деревья
- •3.3.2. Порождение всех каркасов графа
- •3.3.3. Каркас минимального веса. Метод Краскала
- •3.3.4. Каркас минимального веса. Метод Прима
- •3.4. Связность
- •3.4.1. Достижимость
- •3.4.2. Определение связности
- •3.4.3. Двусвязность
- •3.5. Циклы
- •3.5.1. Эйлеровы циклы
- •3.5.2. Гамильтоновы циклы
- •3.5.3. Фундаментальное множество циклов
- •3.6. Кратчайшие пути
- •3.6.1. Постановка задачи. Вывод пути
- •3.6.2. Алгоритм Дейкстры
- •3.6.3. Пути в бесконтурном графе
- •3.6.4. Кратчайшие пути между всеми парами вершин. Алгоритм Флойда
- •3.7. Независимые и доминирующие множества
- •3.7.1. Независимые множества
- •3.7.2. Метод генерации всех максимальных независимых множеств графа
- •3.7.3. Доминирующие множества
- •3.7.4. Задача о наименьшем покрытии
- •3.7.5. Метод решения задачи о наименьшем разбиении
- •3.8 Раскраски
- •3.8.1 Правильные раскраски
- •3.8.2. Поиск минимальной раскраски вершин графа
- •3.8.3. Использование задачи о наименьшем покрытии при раскраске вершин графа
- •3.9. Потоки в сетях, паросочетания
- •3.9.1. Постановка задачи
- •3.9.2. Метод построения максимального потока в сети
- •3.9.3. Наибольшее паросочетание в двудольном графе
- •3.10. Методы приближенного решения задачи коммивояжера
- •3.10.1. Метод локальной оптимизации
- •3.10.2. Алгоритм Эйлера
- •2.10.3. Алгоритм Кристофидеса
- •3.11. Задачи
3.4.2. Определение связности
Определения. Неориентированный граф G связен, если существует хотя бы один путь в G между каждой парой вершин i и j. Ориентированный граф G связен, если неориентированный граф, получающийся из G путем удаления ориентации ребер, является связным. Ориентированный граф сильно связен, если для каждой пары вершин i и j существует по крайней мере один ориентированный путь из i в j и по крайней мере один из j в i. Максимальный связный подграф графа G называется связной компонентой графа G. Максимальный сильно связный подграф называется сильно связной компонентой.
Дополнения.
1. Доказать, что в конденсации графа не содержится циклов.
2. Доказать, что в ориентированном графе каждая вершина i может принадлежать только одной сильной компоненте.
3. В графе есть множество вершин P, из которых достижима любая вершина графа и которое является минимальным в том смысле, что не существует подмножества в P, обладающего таким свойством достижимости. Это множество вершин называется базой графа. Показать, что в P нет двух вершин, которые принадлежат одной и той же сильной компоненте графа G.
Показать, что любые две базы графа G имеют одно и то же число вершин.
Разработать программу нахождения базы графа. Схема решения. База P* конденсации G* графа G состоит из таких вершин графа G*, в которые не заходят ребра. Следовательно, базы графа G можно строить так: из каждой сильной компоненты графа G, соответствующей вершине базы P* конденсации G*, надо взять по одной вершине - это и будет базой графа G.
3.4.3. Двусвязность
Иногда недостаточно знать, что граф связен. Может возникнуть вопрос, насколько “сильно связен” связный граф. Например, в графе может существовать вершина, удаление которой вместе с инцидентными ей ребрами разъединяет оставшиеся вершины. Такая вершина называется точкой сочленения, или разделяющей вершиной. Граф, содержащий точку сочленения, называется разделимым. Граф без точек сочленения называется двусвязным или неразделимым. Максимальный двусвязный подграф графа называется двусвязной компонентой или блоком.
Пример. Разделимый граф и его двусвязные компоненты. Точки сочленения вершины с номерами 4, 5 и 7.
Что нам это дает? Пусть очередность просмотра вершин в процессе поиска в глубину фиксируется метками в массиве Num. Для нашего примера Num - (1,2,3,4,5,6,7,9,8). Если мы рассматриваем обратное ребро (v,u), и v не предок u, то информацию о том, что Num[v] больше Num[u], можно использовать для пометки вершин v и u как вершин, принадлежащих одной компоненте двусвязности. Массив Num использовать для этих целей нельзя, поэтому введем другой массив Lowpg и постараемся пометить вершины графа, принадлежащие одной компоненте двусвязности одним значением метки в этом массиве. Первоначальное значение метки совпадает со значением соответствующего элемента массива Num. При нахождении обратного ребра (v,u) естественной выглядит операция: Lowpg[v]:=Min(Lowpg[v],Num[u]) - изменения значения метки вершины v, так как вершины v и u из одной компоненты двусвязности. К этой логике необходимо добавить смену значения метки у вершины v ребра (v,u) на выходе из просмотра в глубину в том случае, если значение метки вершины u меньше, чем метка вершины v (Lowpg[v]:= Min(Lowpg[v],Lowpg[u])). Для нашего примера массив меток Lowpg имеет вид: (1,1,1,2,4,4,4,9,8). Осталось определить момент вывода компоненты двусвязности. Мы рассматриваем ребро (v,u), и оказывается, что значение Lowpg[u] больше или равно значению Num[v]. Это говорит о том, что при просмотре в глубину между вершинами v и u не было обратных ребер. Вершина v - точка сочленения, и необходимо вывести очередную компоненту двусвязности, начинающуюся с вершины v.
Итак, логика.
procedure Dvy(v,p:integer);{вершина p - предок вершины v}
{массивы A, Num, Lowpg и переменная nm - глобальные}
var u:integer;
begin
Inc(nm);Num[v]:=nm;Lowpg[v]:=Num[v];
for u:=1 to N do
if A[v,u]<>0 then if Num[u]=0 then begin
<сохранить ребро (v,u) в стеке>;
Dvy(u,v);
Lowpg[v]:=Min(Lowpg[v],Lowpg[u]);
{функция, определяющая минимальное из двух чисел }
if Lowpg[u]>=Num[v] then <вывод компоненты>;
end
else if (u<>p) and (Num[v]>Num[u]) then begin
{u не совпадает с предком вершины v}
<сохранить ребро (v,u) в стеке>;
Lowpg[v]:=Min(Lowpg[v],Num[u]);
end;
end;
Фрагмент основной логики:
....
FillChar(Num,SizeOf(Num),0);
FillChar(Lowpg,SizeOf(Lowpg),0);
nm:=0;
for v:=1 to N do if Num[v]=0 then Dvy(v,0);
....
Дополнение. Мостом графа G называется каждое ребро, удаление которого приводит к увеличению числа связных компонент графа. Разработать программу нахождения всех мостов графа. Покажите, что мосты графа должны быть в каждом каркасе графа G. Каким образом знание мостов графа может изменить (ускорить) логику нахождения всех его каркасов?