Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsii_TRPO / Krusk+Prima_lec.doc
Скачиваний:
63
Добавлен:
12.03.2015
Размер:
1.14 Mб
Скачать

8. Деревья.

Деревом называют связный неориентированный граф без циклов. Иначе, связный граф, содержащий N вершин и N-1 ребер.

Для связного неориентированного графа G = < V, E > каждое дерево < V, T > , где TE называют стягивающим деревом (каркасом, остовом). Число различных каркасов полного связного неориентированного графа с N вершинами равно NN-2 (Кэли)(рис. 7.1).

Рассмотрим два алгоритма нахождения каркаса (одного), основанных на методах просмотра графа поиском в глубину и в ширину.

7.1. Выделение дерева методом поиска в глубину и в ширину.

Известно, что как при поиске в глубину, так и при поиске в ширину просматриваются все вершины связного графа. Использование множества Т обеспечивает «подключение» очередного ребра к каркасу без образования циклов. Действительно, цикл образуется, если мы соединим две просмотренные вершины. Но в нашем случае «подключается» ребро, соединяющее просмотренную вершину с непросмотренной. И, наконец, по самой логике методов поиска в глубину и в ширину мы строим связный граф.

Для хранения ребер, образующих каркас, будем использовать структуру данных :

B :Array [1..2,1..n] Of Integer; { Столбец j матрицы B содержит две

вершины, инцидентные ребру j}

z :Integer; {z – индекс для B}

Построение остовного дерева (каркаса) методом поиска в глубину.

Procedure Tree_Gl ( v :Integer ); {рекурсивный вариант}

Var j :Integer;

Begin

T := T + [ v ];

Write(v:3);

For j := 1 To n Do

If ( A [v, j] <> 0 ) And Not ( T In [ j ] )

Then Begin Inc(z); B[1,z]:=v; B[2,z]:=j; {добавляем ветвь в остов}

Tree_Gl ( j );

End;

End;

Вызов: … s:=1; z:=0; T:=[ ]; Tree_Gl(s); Вывод матрицы B;

Построение остовного дерева (каркаса) методом поиска в ширину.

Procedure Tree_SH ( v: Integer); { Поиск в ширину}

Var j :Integer;

Begin

r := 0; w := 1; Q[w] := v; { начальную вершину -> в очередь }

T:=[ v ];

While r < w Do Begin { пока очередь не пуста }

Inc( r ); v := Q[ r ]; {берем очередную вершину из очереди }

Write( v:3 );

For j := 1 To n Do { всех непросмотренных потомков этой вершины}

If (A[ v, j ] <> 0 ) And Not ( j In T ) { записываем в очередь }

Then Begin Inc( w ); Q[ w ] := j; T := T + [ j ];

Inc( z ); B[ 1, z ] :=v; B[ 2, z ] := j;

End;

End;

End;

Вызов: … s:=1; z :=0; SH_Obhod ( s ); Вывод матрицы B; …

Порождение всех каркасов графа

Для порождения очередного каркаса ранее построенные не привлекаются, используется только последний. Множество всех каркасов делится на два класс: содержащие выделенное ребро < v, u > и не содержащие его. Каркасы последовательно строятся в графах G< v, u > и G - < v, u >. Каждый из графов G< v, u > и G - < v, u > меньше, чем G. Последовательное применение этого шага уменьшает графы до тех пор, пока не будет построен очередной каркас либо графы станут несвязными и не имеющими каркасов. Пример графа и его каркасов в той последовательности, в которой они порождаются данным методом, приведен на рис 7.3.

Пусть:

Q :Array [1..nq] Of Integer; {очередь}

r, w :Integer; {r,w -индексы чтения и записи в очередь}

B :Array [1..2,1..n] Of Integer; {массив для ребер каракаса}

z :Integer; { индекс для массива B}

v – номер вершины, из которой выходит ребро;

u – номер вершины, начиная с которой следует искать очередное

ребро каркаса;

k – число ребер в каждом каркасе.

Procedure Ostov ( v, u :Integer ); {Построение всех каркасов графа

Var j :Integer; (рекурсивный алгоритм)}

Begin

If r >= w Then Exit;

j := u;

While ( j <= n ) And ( z < k ) Do Begin {просмотр ребер выходящих из v}

If (A[ v, j ] <> 0 ) And Not ( j In T ) Then Begin { есть ребро < v ,j >,

T := T + [ j ]; причем вершина j еще не просмотрена

Inc( z ); B [ 1, z ] := v; B [ 2, z ] := j; включаем это ребро в каркас

Q[ w ] := j; Inc( w ); а вершину j в очередь

Ostov ( v, j+1 ); и едем вперед}

Dec ( w ); T := T - [ j ]; Dec ( z ) ; {исключаем ребро из каркаса}

End;

Inc ( j );

End;

If z = k Then Begin WriteOstov( B, k ); Exit; End;

If j = n + 1 Then

Begin Inc( r ); {все ребра, выходящие из вершины v просмотрены,

Ostov( Q[ r ], 1 ); переходим к следующей вершине из очереди и

Dec( r ); так до тех пор, пока не будет построен каркас}

End;

End;

Begin … Q[1]:=1; r:=1; w:=2; z:=0; k:=3; T :=[1]; Ostov(1,2); … End;

Соседние файлы в папке Lektsii_TRPO