Алгоритмы на графах (на псевдокоде) / 2_связ_и_сильно_связ
.docНахождение сильно связных компонент графа (ССК)
(на основе поиска в глубину) - Strong Connection
procedure STRONG ( v: Vert );
global
NumVert : Array [1..n] of Nat0n; {Nat0n=0..n}
Adj: array [1..n] of ListVert; { списки смежности }
iV: Nat0n; {текущий порядковый номер посещения вершины}
LowLink: Array [1..n] of Nat0n;
St: Stack of V; {стек для записи вершин}
begin
iV := iV + 1; { посетить v}
NumVert[v] := iV; LowLink[v] := NumVert[v];
St v;
for w Adj[v] do
if NumVert[w]=0 then
begin { <v,w> - ребро (ветвь) остовного дерева }
STRONG ( w );
LowLink[v] := min (LowLink[v],LowLink[w]);
end
else { w - уже посещалась }
if (NumVert[w] < NumVert[v]) then
{ <v,w> - обратное или поперечное ребро }
if w St then
{w находится в той же ССК, что и v, поскольку
w Adj[v] и w St означает, что существует путь из w в v}
LowLink[v] := min ( LowLink[v],NumVert[w] )
{fi}
{fi}
{od}; { v - использована }
if LowLink[v] = NumVert[v] then { v - корень ССК }
while x с вершины стека St удовлетворяет соотношению (NumVert[x] >= NumVert[v]) do
begin
добавить x к текущей ССК;
исключить x из St
end
{fi}
end {STRONG};
Главная программа нахождения сильно связных компонент графа G=(V,E)
var
V : SetVert; {множество вершин графа G=(V,E), Card(V)=n }
NumVert : Array [1..n] of Nat0n; {Nat0n=0..n}
Adj: array [1..n] of ListVert; { списки смежности }
iV: Nat0n; {текущий порядковый номер посещения вершины}
LowLink: Array [1..n] of Nat0n;
St: Stack of V; {стек для записи вершин}
begin
for v V do NumVert[v] := 0;
{ - пометить все вершины как необследованные }
iV := 0; Empty(St);
for v V do
if NumVert[v]=0 then STRONG (v)
end
Нахождение компонент двусвязности графа (BiConnection)
(на основе поиска в глубину)
Использованы обозначения для множества P(v) и функции Low(v):
P(v) = {v} U { w : (w=предок(v)) & ( x V: ((x=v) (x=потомок(v))) & (<x,w> B))},
где B - множество обратных ребер (хорд); Low(v) = Min { NumVert(x) : x P(v) }.
procedure BICON ( v, u: Vert ); { посещаем вершину v и т.д.; u=Отец(v) }
global
NumVert : Array [1..n] of Nat0n; {Nat0n=0..n}
Adj: array [1..n] of ListVert; { списки смежности }
iV: Nat0n; {текущий порядковый номер посещения вершины}
Low: Array [1..n] of Nat0n;
St: Stack of E; {стек для записи ребер}
begin
iV := iV + 1; { посетить v}
NumVert[v] := iV; Low[v] := NumVert[v];
for w Adj[v] do
if NumVert[w]=0 then
begin { <v,w> - ребро (ветвь) остовного дерева }
St <-- {v,w};
BICON ( w, v);
Low[v] := min (Low[v],Low[w]);
if Low[w] >= NumVert[v] then
begin { v - либо корень, либо точка сочленения, а в стеке
сверху до <v,w> включительно - ребра компоненты
двувязности; выписать (зафиксировать) их }
repeat
e <-- St;
Write(e);
until e = {v,w};
WriteLn('end of Block')
end {if}
end
else { w - уже посещалась }
if (NumVert[w] < NumVert[v]) & (w<>u) then
begin { <v,w> - обратное ребро (хорда), включаем в стек }
St <-- {v,w};
Low[v] := min ( Low[v],NumVert[w] )
end {if}
{fi}
{od} { v - использована }
end {BICON};
Главная программа нахождения компонент двусвязности графа G=(V,E)
Var V : SetVert; {множество вершин графа G=(V,E), Card(V)=n }
NumVert : Array [1..n] of Nat0n; {Nat0n=0..n}
Adj: array [1..n] of ListVert; { списки смежности }
iV: Nat0n; {текущий порядковый номер посещения вершины}
Low: Array [1..n] of Nat0n;
St: Stack of E; {стек для записи ребер}
begin
for v V do NumVert[v] := 0; { - пометить все вершины как необследованные }
iV := 0; Empty(St);
for v V do if NumVert[v]=0 then BICON (v,v)
end