Você está na página 1de 26

Algoritmos em Grafos

ltima alterao: 26 de Abril de 2004

Transparncias elaboradas por Charles Ornelas Almeida e Nivio Ziviani


Projeto de Algoritmos Cap.7 Algoritmos em Grafos 1
Motivao
Muitas aplicaes em computao
necessitam considerar conjunto de conexes
entre pares de objetos:
Existe um caminho para ir de um objeto a
outro seguindo as conexes?
Qual a menor distncia entre um objeto
e outro objeto?
Quantos outros objetos podem ser
alcanados a partir de um determinado
objeto?
Existe um tipo abstrato chamado grafo que
usado para modelar tais situaes.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos 2
Aplicaes
Alguns exemplos de problemas prticos que
podem ser resolvidos atravs de uma
modelagem em grafos:
Ajudar mquinas de busca a localizar
informao relevante na Web.
Descobrir os melhores casamentos entre
posies disponveis em empresas e
pessoas que aplicaram para as posies
de interesse.
Descobrir qual o roteiro mais curto para
visitar as principais cidades de uma regio
turstica.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 3
Conceitos Bsicos
Grafo: conjunto de vrtices e arestas.
Vrtice: objeto simples que pode ter nome e
outros atributos.
Aresta: conexo entre dois vrtices.
0 1
2
4
3
aresta
vrtice
Notao: G = (V, A)
G: grafo
V: conjunto de vrtices
A: conjunto de arestas
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 4
Grafos Direcionados
Um grafo direcionado G um par (V, A), onde
V um conjunto nito de vrtices e A uma
relao binria em V .
Uma aresta (u, v) sai do vrtice u e entra
no vrtice v. O vrtice v adjacente ao
vrtice u.
Podem existir arestas de um vrtice para
ele mesmo, chamadas de self-loops.
0 1
2
4
5 3
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 5
Grafos No Direcionados
Um grafo no direcionado G um par (V, A),
onde o conjunto de arestas A constitudo de
pares de vrtices no ordenados.
As arestas (u, v) e (v, u) so consideradas
como uma nica aresta. A relao de
adjacncia simtrica.
Self-loops no so permitidos.
0 1
2
4
5 3
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 6
Grau de um Vrtice
Em grafos no direcionados:
O grau de um vrtice o nmero de
arestas que incidem nele.
Um vrice de grau zero dito isolado ou
no conectado.
Ex.: O vrtice 1 tem
grau 2 e o vrtice 3
isolado.
0 1
2
4
5 3
Em grafos direcionados
O grau de um vrtice o nmero de
arestas que saem dele (out-degree) mais
o nmero de arestas que chegam nele
(in-degree).
Ex.: O vrtice 2 tem
in-degree 2, out-degree
2 e grau 4.
0 1
2
4
5 3
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 7
Caminho entre Vrtices
Um caminho de comprimento k de um
vrtice x a um vrtice y em um grafo
G = (V, A) uma seqncia de vrtices
(v
0
, v
1
, v
2
, . . . , v
k
) tal que x = v
0
e y = v
k
, e
(v
i1
, v
i
) A para i = 1, 2, . . . , k.
O comprimento de um caminho o nmero
de arestas nele, isto , o caminho contm os
vrtices v
0
, v
1
, v
2
, . . . , v
k
e as arestas
(v
0
, v
1
), (v
1
, v
2
), . . . , (v
k1
, v
k
).
Se existir um caminho c de x a y ento y
alcanvel a partir de x via c.
Um caminho simples se todos os vrtices
do caminho so distintos.
Ex.: O caminho (0, 1, 2, 3) simples e tem
comprimento 3. O caminho (1, 3, 0, 3) no
simples.
0 1
2
4
5 3
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 8
Ciclos
Em um grafo direcionado:
Um caminho (v
0
, v
1
, . . . , v
k
) forma um ciclo
se v
0
= v
k
e o caminho contm pelo
menos uma aresta.
O ciclo simples se os vrtices
v
1
, v
2
, . . . , v
k
so distintos.
O self-loop um ciclo de tamanho 1.
Dois caminhos (v
0
, v
1
, . . . , v
k
) e
(v

0
, v

1
, . . . , v

k
) formam o mesmo ciclo se
existir um inteiro j tal que v

i
= v
(i+j) mod k
para i = 0, 1, . . . , k 1.
Ex.: O caminho (0, 1, 2, 3, 0) forma um ciclo. O
caminho(0, 1, 3, 0) forma o mesmo ciclo que os
caminhos (1, 3, 0, 1) e (3, 0, 1, 3).
0 1
2
4
5 3
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 9
Ciclos
Em um grafo no direcionado:
Um caminho (v
0
, v
1
, . . . , v
k
) forma um ciclo
se v
0
= v
k
e o caminho contm pelo
menos trs arestas.
O ciclo simples se os vrtices
v
1
, v
2
, . . . , v
k
so distintos.
Ex.: O caminho (0, 1, 2, 0) um ciclo.
0 1
2
4
5 3
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 10
Componentes Conectados
Um grafo no direcionado conectado se
cada par de vrtices est conectado por um
caminho.
Os componentes conectados so as pores
conectadas de um grafo.
Um grafo no direcionado conectado se ele
tem exatamente um componente conectado.
Ex.: Os componentes so: {0, 1, 2}, {4, 5} e {3}.
0 1
2
4
5 3
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 11
Componentes Fortemente Conectados
Um grafo direcionado G = (V, A)
fortemente conectado se cada dois vrtices
quaisquer so alcanveis a partir um do
outro.
Os componentes fortemente conectados
de um grafo direcionado so conjuntos de
vrtices sob a relao so mutuamente
alcanveis.
Um grafo direcionado fortemente
conectado tem apenas um componente
fortemente conectado.
Ex.: {0, 1, 2, 3}, {4} e {5} so os componentes
fortemente conectados, {4, 5} no o pois o
vrtice 5 no alcanvel a partir do vrtice 4.
0 1
2
4
5 3
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 12
Grafos Isomorfos
G = (V, A) e G

= (V

, A

) so isomorfos se
existir uma bijeo f : V V

tal que
(u, v) A se e somente se (f(u), f(v)) A

.
4 5
6 7
0 1
2 3
s w x t
u y z v
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 13
Subgrafos
Um grafo G

= (V

, A

) um subgrafo de
G = (V, A) se V

V e A

A.
Dado um conjunto V

V , o subgrafo
induzido por V

o grafo G

= (V

, A

), onde
A

= {(u, v) A|u, v V

}.
Ex.: Subgrafo induzido pelo conjunto de vrtices
{1, 2, 4, 5}.
0 1
2
4
5 3
2
1 4
5
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 14
Verso Direcionada de um Grafo No
Direcionado
A verso direcionada de um grafo no
direcionado G = (V, A) um grafo
direcionado G

= (V

, A

) onde (u, v) A

se e
somente se (u, v) A.
Cada aresta no direcionada (u, v) em G
substituda por duas arestas direcionadas
(u, v) e (v, u)
Em um grafo direcionado, um vizinho de um
vrtice u qualquer vrtice adjacente a u na
verso no direcionada de G.
0 1
2
0 1
2
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 15
Verso No Direcionada de um Grafo
Direcionado
A verso no direcionada de um grafo
direcionado G = (V, A) um grafo no
direcionado G

= (V

, A

) onde (u, v) A

se e
somente se u = v e (u, v) A.
A verso no direcionada contm as arestas
de G sem a direo e sem os self-loops.
Em um grafo no direcionado, u e v so
vizinhos se eles so adjacentes.
0 1
2
4
5 3
0
3
1
2
4
5
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 16
Outras Classicaes de Grafos
Grafo ponderado: possui pesos associados
s arestas.
Grafo bipartido: grafo no direcionado
G = (V, A) no qual V pode ser particionado
em dois conjuntos V
1
e V
2
tal que (u, v) A
implica que u V
1
e v V
2
ou u V
2
e v V
1
(todas as arestas ligam os dois conjuntos V
1
e
V
2
).
Hipergrafo: grafo no direcionado em que
cada aresta conecta um nmero arbitrrio de
vrtices.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 17
Grafos Completos
Um grafo completo um grafo no
direcionado no qual todos os pares de
vrtices so adjacentes.
Possui (|V |
2
|V |)/2 = |V |(|V | 1)/2 arestas,
pois do total de |V |
2
pares possveis de
vrtices devemos subtrair |V | self-loops e
dividir por 2 (cada aresta ligando dois vrtices
contada duas vezes).
O nmero total de grafos diferentes com |V |
vrtices 2
|V |(|V |1)/2
(nmero de maneiras
diferentes de escolher um subconjunto a
partir de |V |(|V | 1)/2 possveis arestas).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1 18
rvores
rvore livre: grafo no direcionado acclico e
conectado. comum dizer apenas que o
grafo uma rvore omitindo o livre.
Floresta: grafo no direcionado acclico,
podendo ou no ser conectado.
rvore geradora de um grafo conectado
G = (V, A): subgrafo que contm todos os
vrtices de G e forma uma rvore.
Floresta geradora de um grafo G = (V, A):
subgrafo que contm todos os vrtices de G e
forma uma oresta.
(b) (a)
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2 19
O Tipo Abstratos de Dados Grafo
Importante considerar os algoritmos em
grafos como tipos abstratos de dados.
Conjunto de operaes associado a uma
estrutura de dados.
Independncia de implementao para as
operaes.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2 20
Operadores do TAD Grafo
1. FGVazio(Grafo): Cria um grafo vazio.
2. InsereAresta(V1,V2,Peso, Grafo): Insere uma
aresta no grafo.
3. ExisteAresta(V1,V2,Grafo): Verica se existe
uma determinada aresta.
4. Obtem a lista de vrtices adjacentes a um
determinado vrtice (tratada a seguir).
5. RetiraAresta(V1,V2,Peso, Grafo): Retira uma
aresta do grafo.
6. LiberaGrafo(Grafo): Liberar o espao
ocupado por um grafo.
7. ImprimeGrafo(Grafo): Imprime um grafo.
8. GrafoTransposto(Grafo,GrafoT): Obtm o
transposto de um grafo direcionado.
9. RetiraMin(A): Obtm a aresta de menor peso
de um grafo com peso nas arestas.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2 21
Operao Obter Lista de Adjacentes
1. ListaAdjVazia(v, Grafo): retorna true se a lista
de adjacentes de v est vazia.
2. PrimeiroListaAdj(v, Grafo): retorna o
endereo do primeiro vrtice na lista de
adjacentes de v.
3. ProxAdj(v, Grafo, u, Peso, Aux, FimListaAdj):
retorna o vrtice u (apontado por Aux) da lista
de adjacentes de v, bem como o peso da
aresta (v, u). Ao retornar, Aux aponta para o
prximo vrtice da lista de adjacentes de v, e
FimListaAdj retorna true se o nal da lista de
adjacentes foi encontrado.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2 22
Implementao da Operao Obter
Lista de Adjacentes
comum encontrar um pseudo comando do
tipo:
for u ListaAdjacentes (v) do { faz algo com u }
O trecho de programa abaixo apresenta um
possvel renamento do pseudo comando
acima.
i f not ListaAdjVazia(v, Grafo)
then begin
Aux : = PrimeiroListaAdj (v, Grafo) ;
FimListaAdj : = false;
while not FimListaAdj
do ProxAdj (v, Grafo, u, Peso, Aux, FimListaAdj ) ;
end;
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1 23
Matriz de Adjacncia
A matriz de adjacncia de um grafo
G = (V, A) contendo n vrtices uma matriz
n n de bits, onde A[i, j] 1 (ou verdadeiro)
se e somente se existe um arco do vrtice i
para o vrtice j.
Para grafos ponderados A[i, j] contm o
rtulo ou peso associado com a aresta e,
neste caso, a matriz no de bits.
Se no existir uma aresta de i para j ento
necessrio utilizar um valor que no possa
ser usado como rtulo ou peso.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1 24
Matriz de Adjacncia - Exemplo
0 1
2
4
5 3
0 1
2
4
5 3
1
1
1
0
1
2
3
4
5
1
1 1
1 1
1 1
0 1 2 3 4 5
0
1
2
3
4
5
(a)
0 1 2 5
1
1
1
(b)
3 4
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1 25
Matriz de Adjacncia - Anlise
Deve ser utilizada para grafos densos, onde
|A| prximo de |V |
2
.
O tempo necessrio para acessar um
elemento independente de |V | ou |A|.
muito til para algoritmos em que
necessitamos saber com rapidez se existe
uma aresta ligando dois vrtices.
A maior desvantagem que a matriz
necessita (|V |
2
) de espao. Ler ou examinar
a matriz tem complexidade de tempo O(|V |
2
).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1 26
Matriz de Adjacncia - Implementao
A insero de um novo vrtice ou retirada de
um vrtice j existente pode ser realizada
com custo constante.
const MaxNumVertices = 100;
MaxNumArestas = 4500;
type
TipoValorVertice = 0. .MaxNumVertices;
TipoPeso = integer ;
TipoGrafo = record
Mat : array[ TipoValorVertice , TipoValorVertice]
of TipoPeso;
NumVertices: 0. .MaxNumVertices;
NumArestas : 0. .MaxNumArestas;
end;
Apontador = TipoValorVertice;
procedure FGVazio(var Grafo: TipoGrafo) ;
var i , j : integer ;
begin
for i : = 0 to Grafo.NumVertices do
for j : = 0 to Grafo.NumVertices do Grafo.mat[ i , j ] : = 0;
end;
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1 27
Matriz de Adjacncia - Implementao
procedure InsereAresta ( var V1, V2: TipoValorVertice;
var Peso : TipoPeso;
var Grafo : TipoGrafo) ;
begin
Grafo.Mat[V1, V2] : = peso;
end;
function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice;
var Grafo: TipoGrafo) : boolean;
begin
ExisteAresta : = Grafo.Mat[ Vertice1 , Vertice2] > 0;
end; { ExisteAresta }
{Operador para obter a l i st a de adjacentes}
function ListaAdjVazia ( var Vertice : TipoValorVertice;
var Grafo: TipoGrafo) : boolean;
var Aux: Apontador ; ListaVazia: boolean;
begin
ListaVazia : = true; Aux : = 0;
while (Aux < Grafo.NumVertices) and ListaVazia do
i f Grafo.Mat[ Vertice , Aux] > 0
then ListaVazia : = false
else Aux : = Aux + 1;
ListaAdjVazia : = ListaVazia = true;
end; { ListaAdjVazia }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1 28
Matriz de Adjacncia - Implementao
{Operador para obter a l i st a de adjacentes}
function PrimeiroListaAdj ( var Vertice : TipoValorVertice;
var Grafo: TipoGrafo) : Apontador;
var Aux: Apontador ; Listavazia : boolean;
begin
ListaVazia : = true; Aux : = 0;
while (Aux < Grafo.NumVertices) and ListaVazia do
i f Grafo.Mat[ Vertice , Aux] > 0
then begin PrimeiroListaAdj : = Aux; ListaVazia : = false;
end
else Aux : = Aux + 1;
i f Aux = Grafo.NumVertices
then writeln( Erro: Lista adjacencia vazia ( PrimeiroListaAdj ) ) ;
end; { PrimeiroListaAdj }
{Operador para obter a l i st a de adjacentes}
procedure ProxAdj ( var Vertice : TipoValorVertice ; var Grafo: TipoGrafo;
var Adj : TipoValorVertice ; var Peso: TipoPeso;
var Prox: Apontador ; var FimListaAdj : boolean) ;
{ Retorna Adj apontado por Prox}
begin
Adj := Prox; Peso : = Grafo.Mat[ Vertice , Prox] ; Prox : = Prox + 1;
while ( Prox < Grafo.NumVertices) and
(Grafo.Mat[ Vertice , Prox] = 0) do Prox : = Prox + 1;
i f Prox = Grafo.NumVertices then FimListaAdj : = true;
end; { ProxAdj }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1 29
Matriz de Adjacncia - Implementao
procedure RetiraAresta ( var V1, V2: TipoValorVertice;
var Peso : TipoPeso;
var Grafo : TipoGrafo) ;
begin
i f Grafo.Mat[V1, V2] = 0
then writeln( Aresta nao existe )
else begin Peso : = Grafo.Mat[V1, V2] ; Grafo.Mat[V1, V2] : = 0;
end;
end; { RetiraAresta }
procedure LiberaGrafo ( var Grafo: TipoGrafo) ;
begin { Nao faz nada no caso de matrizes de adjacencia }
end; { LiberaGrafo }
procedure ImprimeGrafo ( var Grafo : TipoGrafo) ;
var i , j : integer ;
begin
write( ) ;
for i : = 0 to Grafo.NumVertices1do write( i : 3) ; writeln;
for i : = 0 to Grafo.NumVertices1do
begin
write( i : 3) ;
for j : = 0 to Grafo.NumVertices1do write(Grafo.mat[ i , j ] : 3) ;
writeln;
end;
end; { ImprimeGrafo }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2 30
Listas de Adjacncia usando
Apontadores
5
0 5 2 7
1 7
1
3
2
1
0
5
7
0 1
2 3
3
5
7
3
0 1
2
5
1 3 2 7
1
3
2
1
0
Um arranjo Adj de |V | listas, uma para cada
vrtice em V .
Para cada u V , Adj[u] contm todos os
vrtices adjacentes a u em G.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2 31
Listas de adjacncia - Anlise
Os vrtices de uma lista de adjacncia so
em geral armazenados em uma ordem
arbitrria.
Possui uma complexidade de espao
O(|V | +|A|)
Indicada para grafos esparsos, onde |A|
muito menor do que |V |
2
.
compacta e usualmente utilizada na maioria
das aplicaes.
A principal desvantagem que ela pode ter
tempo O(|V |) para determinar se existe uma
aresta entre o vrtice i e o vrtice j, pois
podem existir O(|V |) vrtices na lista de
adjacentes do vrtice i.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2 32
Listas de Adjacncia usando
Apontadores - Implementao
No uso de apontadores a lista constituda
de clulas, onde cada clula contm um item
da lista e um apontador para a clula
seguinte.
const MaxNumVertices = 100;
MaxNumArestas = 4500;
type
TipoValorVertice = 0. .MaxNumVertices;
TipoPeso = integer ;
TipoItem = record
Vertice : TipoValorVertice;
Peso : TipoPeso;
end;
Apontador = ^Celula;
Celula = record
Item: TipoItem;
Prox: Apontador;
end;
TipoLista = record
Primeiro: Apontador;
Ultimo: Apontador;
end;
TipoGrafo = record
Adj : array[ TipoValorVertice ] of TipoLista;
NumVertices: TipoValorVertice;
NumArestas: 0. .MaxNumArestas;
end;
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2 33
Listas de Adjacncia usando
Apontadores - Implementao
{Entram aqui os operadores FLVazia, Vazia, Insere, Retira e Imprime do
TAD Lista de Apontadores}
procedure FGVazio(var Grafo: TipoGrafo) ;
var i : integer ;
begin
for i : = 0 to Grafo.NumVertices1do FLVazia(Grafo. Adj [ i ] ) ;
end; { FGVazio }
procedure InsereAresta(var V1, V2: TipoValorVertice ; var Peso: TipoPeso;
var Grafo: TipoGrafo) ;
var x: TipoItem;
begin
x. Vertice : = V2; x.Peso : = Peso;
Insere(x, Grafo. Adj [V1] ) ;
end; { InsereAresta }
function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice;
var Grafo: TipoGrafo) : boolean;
var Aux: Apontador;
EncontrouAresta: boolean;
begin
Aux : = Grafo. Adj [ Vertice1 ] . Primeiro^.Prox;
EncontrouAresta : = false;
while (Aux <> ni l ) and ( EncontrouAresta = false) do
begin
i f Vertice2 = Aux^.Item. Vertice then EncontrouAresta : = true;
Aux : = Aux^.Prox;
end;
ExisteAresta : = EncontrouAresta;
end; { ExisteAresta }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2 34
Listas de Adjacncia usando
Apontadores - Implementao
{Operador para obter a l i st a de adjacentes}
function ListaAdjVazia ( var Vertice : TipoValorVertice;
var Grafo: TipoGrafo) : boolean;
begin
ListaAdjVazia : = Grafo. Adj [ Vertice ] . Primeiro =
Grafo. Adj [ Vertice ] . Ultimo;
end; { ListaAdjVazia }
{Operador para obter a l i st a de adjacentes}
function PrimeiroListaAdj ( var Vertice : TipoValorVertice;
var Grafo: TipoGrafo) : Apontador;
begin
PrimeiroListaAdj : = Grafo. Adj [ Vertice ] . Primeiro^.Prox;
end; { PrimeiroListaAdj }
{Operador para obter a l i st a de adjacentes}
procedure ProxAdj ( var Vertice : TipoValorVertice;
var Grafo : TipoGrafo;
var Adj : TipoValorVertice;
var Peso : TipoPeso;
var Prox : Apontador;
var FimListaAdj : boolean) ;
{ Retorna Adj e Peso do Item apontado por Prox}
begin
Adj := Prox^.Item. Vertice;
Peso := Prox^.Item.Peso;
Prox := Prox^.Prox;
i f Prox = ni l then FimListaAdj : = true;
end; { ProxAdj }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2 35
Listas de Adjacncia usando
Apontadores - Implementao
procedure RetiraAresta ( var V1, V2: TipoValorVertice;
var Peso : TipoPeso;
var Grafo : TipoGrafo) ;
var AuxAnterior , Aux: Apontador;
EncontrouAresta: boolean;
x: TipoItem;
begin
AuxAnterior : = Grafo. Adj [V1] . Primeiro;
Aux : = Grafo. Adj [V1] . Primeiro^.Prox;
EncontrouAresta : = false;
while (Aux <> ni l ) and ( EncontrouAresta = false) do
begin
i f V2 = Aux^.Item. Vertice
then begin
Retira(AuxAnterior , Grafo. Adj [V1] , x) ;
Grafo.NumArestas : = Grafo.NumArestas 1;
EncontrouAresta : = true;
end;
AuxAnterior : = Aux; Aux : = Aux^.Prox;
end;
end; { RetiraAresta }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2 36
Listas de Adjacncia usando
Apontadores - Implementao
procedure LiberaGrafo ( var Grafo: TipoGrafo) ;
var AuxAnterior , Aux: Apontador;
begin
for i := 0 to Grafo.NumVertices1do
begin
Aux : = Grafo. Adj [ i ] . Primeiro^.Prox;
dispose(Grafo. Adj [ i ] . Primeiro) ; {Libera celula cabeca}
while Aux <> ni l do
begin AuxAnterior : = Aux; Aux : = Aux^.Prox; dispose(AuxAnterior ) ;
end;
end;
end; { LiberaGrafo }
procedure ImprimeGrafo ( var Grafo : TipoGrafo) ;
var i : integer ; Aux: Apontador;
begin
for i := 0 to Grafo.NumVertices1do
begin
write( Vertice , i :2, : ) ;
i f not Vazia(Grafo. Adj [ i ] )
then begin
Aux : = Grafo. Adj [ i ] . Primeiro^.Prox;
while Aux <> ni l do
begin
write(Aux^.Item. Vertice:3, ( ,Aux^.Item.Peso, ) ) ;
Aux : = Aux^.Prox;
end;
end;
writeln;
end;
end; { ImprimeGrafo }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3 37
Listas de Adjacncia usando Arranjos
6
2
3
1
1
2
4
5
0
0
0
6
0
5
3
7
4
6
7
3
1
0
2
1
4
5
7
0
0
6
0
0
5
5
7
7
4
3 2
1 0
1
2 3
A
V
V
A
5
7
5
7
0
1
2
3
4
5
6
Cab Prox Peso
0
1
2
3
4
5
6
7
Cab Prox Peso
0
3
Cab: endereos do ltimo item da lista de
adjacentes de cada vrtice (nas |V | primeiras
posies) e os vrtices propriamente ditos
(nas |A| ltimas posies)
Prox: endereo do prximo item da lista de
adjacentes.
Peso: valor do peso de cada aresta do grafo
(nas ltimas |A| posies).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3 38
Listas de Adjacncia usando Arranjos
- Implementao
const MaxNumVertices = 100;
MaxNumArestas = 4500;
MaxTam = MaxNumVertices+2MaxNumArestas;
type
TipoValorVertice = 0. .MaxNumVertices;
TipoPeso = integer ;
TipoTam = 0..MaxTam;
TipoGrafo = record
Cab : array[TipoTam] of TipoTam;
Prox : array[TipoTam] of TipoTam;
Peso : array[TipoTam] of TipoTam;
ProxDisponivel : TipoTam;
NumVertices : 0. .MaxNumVertices;
NumArestas : 0. .MaxNumArestas;
end;
Apontador = TipoTam;
procedure FGVazio(var Grafo: TipoGrafo) ;
var i : integer ;
begin
for i : = 0 to Grafo.NumVertices do
begin
Grafo. Prox[ i ] : = 0; Grafo.Cab[ i ] : = i ;
Grafo. ProxDisponivel : = Grafo.NumVertices;
end;
end;
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3 39
Listas de Adjacncia usando Arranjos
- Implementao
procedure InsereAresta ( var V1, V2: TipoValorVertice;
var Peso : TipoPeso;
var Grafo : TipoGrafo) ;
var Pos: integer ;
begin
Pos:= Grafo. ProxDisponivel ;
i f Grafo. ProxDisponivel = MaxTam
then writeln( nao ha espaco disponivel para a aresta )
else begin
Grafo. ProxDisponivel : = Grafo. ProxDisponivel + 1;
Grafo. Prox[ Grafo.Cab[V1] ] : = Pos;
Grafo.Cab[Pos] : = V2; Grafo.Cab[V1] : = Pos;
Grafo. Prox[Pos] : = 0; Grafo.Peso[Pos] : = Peso;
end;
end; { InsereAresta}
function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice;
var Grafo: TipoGrafo) : boolean;
var Aux: Apontador ; EncontrouAresta: boolean;
begin
Aux : = Grafo. Prox[ Vertice1 ] ; EncontrouAresta : = false;
while (Aux <> 0) and ( EncontrouAresta = false) do
begin
i f Vertice2 = Grafo.Cab[Aux] then EncontrouAresta : = true;
Aux : = Grafo. Prox[Aux] ;
end;
ExisteAresta : = EncontrouAresta;
end; { ExisteAresta }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3 40
Listas de Adjacncia usando Arranjos
- Implementao
{Operador para obter a l i st a de adjacentes}
function ListaAdjVazia(var Vertice : TipoValorVertice;
var Grafo: TipoGrafo) : boolean;
begin
ListaAdjVazia : = Grafo. Prox[ Vertice] = 0;
end; { ListaAdjVazia }
{Operador para obter a l i st a de adjacentes}
function PrimeiroListaAdj (var Vertice : TipoValorVertice;
var Grafo: TipoGrafo) : Apontador;
begin
PrimeiroListaAdj : = Grafo. Prox[ Vertice ] ;
end; { PrimeiroListaAdj }
{Operador para obter a l i st a de adjacentes}
procedure ProxAdj ( var Vertice : TipoValorVertice;
var Grafo : TipoGrafo;
var Adj : TipoValorVertice;
var Peso : TipoPeso;
var Prox : Apontador;
var FimListaAdj : boolean) ;
{ Retorna Adj apontado por Prox}
begin
Adj := Grafo.Cab[ Prox] ; Peso : = Grafo.Peso[ Prox] ;
Prox : = Grafo. Prox[ Prox] ;
i f Prox = 0 then FimListaAdj : = true;
end; { ProxAdj }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3 41
Listas de Adjacncia usando Arranjos
- Implementao
procedure RetiraAresta ( var V1, V2: TipoValorVertice;
var Peso: TipoPeso; var Grafo: TipoGrafo) ;
var Aux, AuxAnterior : Apontador ; EncontrouAresta: boolean;
begin
AuxAnterior : = V1; Aux : = Grafo. Prox[V1] ;
EncontrouAresta : = false;
while (Aux <> 0) and ( EncontrouAresta = false) do
begin
i f V2 = Grafo.Cab[Aux]
then EncontrouAresta : = true
else begin AuxAnterior : = Aux; Aux : = Grafo. Prox[Aux] ; end;
end;
i f EncontrouAresta
then Grafo.Cab[Aux] : = MaxNumVertices+2MaxNumArestas
{Apenas marca como retirado}
else writeln( Aresta nao existe ) ;
end; { RetiraAresta }
procedure LiberaGrafo ( var Grafo: TipoGrafo) ;
begin {Nada no caso de posicoes contiguas} end; { LiberaGrafo }
procedure ImprimeGrafo ( var Grafo : TipoGrafo) ;
var i : integer ;
begin
writeln( Cab Prox Peso ) ;
for i : = 0 to Grafo.NumVertices+2Grafo.NumArestas1do
writeln( i :2,Grafo.Cab[ i ] : 4 , Grafo. Prox[ i ] : 4 , Grafo.Peso[ i ] : 4) ;
end; { ImprimeGrafo }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3 42
Busca em Profundidade
A busca em profundidade, do ingls
depth-rst search), um algoritmo para
caminhar no grafo.
A estratgia buscar o mais profundo no
grafo sempre que possvel.
As arestas so exploradas a partir do vrtice
v mais recentemente descoberto que ainda
possui arestas no exploradas saindo dele.
Quando todas as arestas adjacentes a v
tiverem sido exploradas a busca anda para
trs para explorar vrtices que saem do
vrtice do qual v foi descoberto.
O algoritmo a base para muitos outros
algoritmos importantes, tais como vericao
de grafos acclicos, ordenao topolgica e
componentes fortemente conectados.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3 43
Busca em Profundidade
Para acompanhar o progresso do algoritmo
cada vrtice colorido de branco, cinza ou
preto.
Todos os vrtices so inicializados branco.
Quando um vrtice descoberto pela
primeira vez ele torna-se cinza, e tornado
preto quando sua lista de adjacentes tenha
sido completamente examinada.
d[v]: tempo de descoberta
t[v]: tempo de trmino do exame da lista de
adjacentes de v.
Estes registros so inteiros entre 1 e 2|V | pois
existe um evento de descoberta e um evento
de trmino para cada um dos |V | vrtices.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3 44
Busca em Profundidade -
Implementao
procedure BuscaEmProfundidade ( var Grafo: TipoGrafo) ;
var Tempo : TipoValorTempo;
x : TipoValorVertice;
d, t : array[ TipoValorVertice ] of TipoValorTempo;
Cor : array[ TipoValorVertice ] of TipoCor;
Antecessor : array[ TipoValorVertice ] of integer ;
{Entra aqui o procedimento VisitaDFS (a seguir)}
begin
Tempo : = 0;
for x : = 0 to Grafo.NumVertices1do
begin Cor[ x] : = branco; Antecessor[ x] := 1; end;
for x : = 0 to Grafo.NumVertices1do
i f Cor[ x] = branco then VisitaDfs(x) ;
end; { BuscaEmProfundidade }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3 45
Busca em Profundidade -
Implementao
procedure VisitaDfs (u: TipoValorVertice) ;
var FimListaAdj : boolean;
Peso : TipoPeso;
Aux : Apontador;
v : TipoValorVertice;
begin
Cor[u] : = cinza; Tempo : = Tempo + 1; d[u] : = Tempo;
writeln( Vi si ta ,u:2, Tempo descoberta: ,d[u] : 2 , cinza ) ; readln;
i f not ListaAdjVazia(u, Grafo)
then begin
Aux : = PrimeiroListaAdj (u, Grafo) ; FimListaAdj : = false;
while not FimListaAdj do
begin
ProxAdj (u, Grafo, v, Peso, Aux, FimListaAdj ) ;
i f Cor[ v] = branco
then begin Antecessor[ v] : = u; VisitaDfs(v) ; end;
end;
end;
Cor[u] : = preto ; Tempo : = Tempo + 1; t [u] : = Tempo;
writeln( Vi si ta ,u:2, Tempo termino: , t [u] : 2 , preto ) ; readln;
end; { VisitaDfs }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3 46
Busca em Profundidade - Exemplo
0 1
2 3
(a)
b( / )
b( / ) b( / )
b( / )
0 1
2 3
(b)
b( / )
c(1/ ) b( / )
b( / )
0 1
2 3
(c)
b( / )
c(1/ ) c(2/ )
b( / )
0 1
2 3
(d)
c(3/ )
b( / )
c(1/ ) c(2/ )
0 1
2 3
(e)
p(3/4)
b( / )
c(1/ ) c(2/ )
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3 47
Busca em Profundidade - Exemplo
0 1
2 3
(f)
p(3/4)
b( / )
c(1/ ) p(2/5)
0 1
2 3
(g)
p(3/4)
b( / )
p(1/6) p(2/5)
0 1
2 3
(h)
p(3/4)
c(7/ )
p(1/6) p(2/5)
0 1
2 3
(i)
p(3/4)
p(7/8)
p(1/6) p(2/5)
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3 48
Busca em Profundidade - Anlise
Os dois anis da BuscaEmProfundidade tm
custo O(|V |) cada um, a menos da chamada
do procedimento VisitaDfs(u) no segundo
anel.
O procedimento VisitaDfs chamado
exatamente uma vez para cada vrtice u V ,
desde que VisitaDfs chamado apenas para
vrtices brancos e a primeira ao pintar o
vrtice de cinza.
Durante a execuo de VisitaDfs(u) o anel
principal executado |Adj[u]| vezes.
Desde que

uV
|Adj[u]| = O(|A|), o tempo
total de execuo de VisitaDfs O(|A|).
Logo, a complexidade total da
BuscaEmProfundidade O(|V | +|A|).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.1 49
Classicao de Arestas
Existem:
1. Arestas de rvore: so arestas de uma
rvore de busca em profundidade. A aresta
(u, v) uma aresta de rvore se v foi
descoberto pela primeira vez ao percorrer a
aresta (u, v).
2. Arestas de retorno: conectam um vrtice u
com um antecessor v em uma rvore de
busca em profundidade (inclui self-loops).
3. Arestas de avano: no pertencem rvore
de busca em profundidade mas conectam um
vrtice a um descendente que pertence
rvore de busca em profundidade.
4. Arestas de cruzamento: podem conectar
vrtices na mesma rvore de busca em
profundidade, ou em duas rvores diferentes.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.1 50
Classicao de Arestas
Classicao de arestas pode ser til para
derivar outros algoritmos.
Na busca em profundidade cada aresta pode
ser classicada pela cor do vrtice que
alcanado pela primeira vez:
Branco indica uma aresta de rvore.
Cinza indica uma aresta de retorno.
Preto indica uma aresta de avano quando
u descoberto antes de v ou uma aresta
de cruzamento caso contrrio.
4
1 2
3 5
0
arv arv
arv
4/5 7/8 11/12
1/10 2/9 3/6
avan
cruz
arv ret
cruz cruz
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.2 51
Teste para Vericar se Grafo Acclico
A busca em profundidade pode ser usada
para vericar se um grafo acclico ou
contm um ou mais ciclos.
Se uma aresta de retorno encontrada
durante a busca em profundidade em G,
ento o grafo tem ciclo.
Um grafo direcionado G acclico se e
somente se a busca em profundidade em G
no apresentar arestas de retorno.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4 52
Busca em Largura
Expande a fronteira entre vrtices
descobertos e no descobertos
uniformemente atravs da largura da
fronteira.
O algoritmo descobre todos os vrtices a uma
distncia k do vrtice origem antes de
descobrir qualquer vrtice a uma distncia
k + 1.
O grafo G(V, A) pode ser direcionado ou no
direcionado.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4 53
Busca em Largura
Cada vrtice colorido de branco, cinza ou
preto.
Todos os vrtices so inicializados branco.
Quando um vrtice descoberto pela
primeira vez ele torna-se cinza.
Vrtices cinza e preto j foram descobertos,
mas so distinguidos para assegurar que a
busca ocorra em largura.
Se (u, v) A e o vrtice u preto, ento o
vrtice v tem que ser cinza ou preto.
Vrtices cinza podem ter alguns vrtices
adjacentes brancos, e eles representam a
fronteira entre vrtices descobertos e no
descobertos.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4 54
Busca em Largura - Implementao
{Entramaqui os operadores FFVazia, Vazia, Enleira e Desenleira do}
{TADFilas comarranjos ou apontadores, dependendo da implementao}
{da busca emlargura usar arranjos ou apontadores, respectivamente}
procedure BuscaEmLargura ( var Grafo: TipoGrafo) ;
var x : TipoValorVertice;
Dist : array[ TipoValorVertice ] of integer ;
Cor : array[ TipoValorVertice ] of TipoCor;
Antecessor : array[ TipoValorVertice ] of integer ;
{Entra aqui o procedimento VisitaBfs (a seguir)}
begin
for x : = 0 to Grafo.NumVertices1do
begin
Cor[ x] : = branco; Dist [ x] : = i nf i ni t o ; Antecessor[ x] := 1;
end;
for x : = 0 to Grafo.NumVertices1do
i f Cor[ x] = branco then VisitaBfs(x) ;
end; { BuscaEmLargura }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4 55
Busca em Largura - Implementao
procedure VisitaBfs (u: TipoValorVertice) ;
var v: TipoValorVertice ; Aux: Apontador ; FimListaAdj : boolean;
Peso: TipoPeso; Item: TipoItem; Fi l a : TipoFila;
begin
Cor[u] : = cinza; Dist [u] : = 0;
FFVazia ( Fi l a ) ; Item. Vertice : = u;
Enfi l ei ra ( Item, Fi l a ) ;
write( Vi si ta origem ,u:2, cor : cinza F: ) ;
ImprimeFila ( Fi l a ) ; readln;
while not FilaVazia ( Fi l a ) do
begin
Desenfileira ( Fila , Item) ; u : = Item. vertice;
i f not ListaAdjVazia(u, Grafo)
then begin
Aux : = PrimeiroListaAdj (u, Grafo) ; FimListaAdj : = false;
while FimListaAdj = false do
begin
ProxAdj (u, v, Peso, Aux, FimListaAdj ) ;
i f Cor[ v] = branco
then begin
Cor[ v] : = cinza; Dist [ v] : = Dist [u] + 1;
Antecessor[ v] : = u;
Item. Vertice : = v; Item.Peso : = Peso;
Enfi l ei ra ( Item, Fi l a ) ;
end;
end;
end;
Cor[u] : = preto;
write( Vi si ta , u:2, Dist , Dist [u] : 2 , cor : preto F: ) ;
ImprimeFila ( Fi l a ) ; readln;
end;
end; { VisitaBfs }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4 56
Busca em Largura - Exemplo
0 1
2 3
4
b( )
5
b( )
2 3
p(0) p(1)
c(2) c(1)
(c)
F
2 1
0 1
2 3
4
b( )
b( ) b( )
5
b( )
0 F
0
c(0) b( )
(a)
0 1
2 3
4
b( )
b( )
5
b( )
1 3 F
1 1
p(0) c(1)
c(1)
(b)
0 1
2 3
4
b( )
5
b( )
2
p(0)
c(2) p(1)
p(1)
(d)
F
2
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4 57
Busca em Largura - Exemplo
0 1
2 3
4
5
F
p(0) p(1) p(0)
p(1) p(2) p(1)
(h)
0 1
2 3
4
5
b( )
4 F
0
c(0)
p(1)
p(0) p(1)
p(2)
(f)
0 1
2 3
4
5
5 F
1
p(0) p(0) p(1)
p(2) p(1) c(1)
(g)
0 1
2 3
4
b( )
5
b( )
F
p(0) p(1)
p(1) p(2)
(e)
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4 58
Busca em Largura - Anlise (para
listas de adjacncia)
O custo de inicializao do primeiro anel em
BuscaEmLargura O(|V |) cada um.
O custo do segundo anel tambm O(|V |).
VisitaBfs: enleirar e desenleirar tm custo
O(1), logo, o custo total com a la O(|V |).
Cada lista de adjacentes percorrida no
mximo uma vez, quando o vrtice
desenleirado.
Desde que a soma de todas as listas de
adjacentes O(|A|), o tempo total gasto com
as listas de adjacentes O(|A|).
Complexidade total: O(|V | +|A|).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4 59
Caminhos Mais Curtos
A busca em largura obtm o caminho mais
curto de u at v.
O procedimento VisitaBfs contri uma rvore
de busca em largura que armazenada na
varivel Antecessor.
O programa abaixo imprime os vrtices do
caminho mais curto entre o vrtice origem e
outro vrtice qualquer do grafo, a partir do
vetor Antecessor obtido na busca em largura.
procedure ImprimeCaminho (Origem, v: TipovalorVertice) ;
begin
i f Origem = v
then write(Origem:3)
else i f Antecessor[ v] = 1
then write( Nao existe caminho de ,Origem:3, ate ,v:3)
else begin
Imprimecaminho(Origem, Antecessor[ v] ) ;
write(v: 3) ;
end;
end; { ImprimeCaminho }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5 60
Ordenao Topolgica
Ordenao linear de todos os vrtices, tal que
se G contm uma aresta (u, v) ento u
aparece antes de v.
Pode ser vista como uma ordenao de seus
vrtices ao longo de uma linha horizontal de
tal forma que todas as arestas esto
direcionadas da esquerda para a direita.
Pode ser feita usando a busca em
profundidade.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5 61
Ordenao Topolgica
Os grafos direcionados acclicos so usados
para indicar precedncias entre eventos.
Uma aresta direcionada (u, v) indica que a
atividade u tem que ser realizada antes da
atividade v.
0
1
4
5
6
7
8
9
2
3
0 5 1 2 4 6 7 8 3 9
4/5
1/18
3/14 6/13
7/12
9/10
19/20 16/17
8/11
2/15
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5 62
Ordenao Topolgica
Algoritmo para ordenar topologicamente um
grafo direcionado acclico G = (V, A):
1. Chama BuscaEmProfundidade(G) para
obter os tempos de trmino t[u] para cada
vrtice u.
2. Ao trmino de cada vrtice insira-o na
frente de uma lista linear encadeada.
3. Retorna a lista encadeada de vrtices.
A Custo O(|V | +|A|), uma vez que a busca
em profundidade tem complexidade de tempo
O(|V | +|A|) e o custo para inserir cada um
dos |V | vrtices na frente da lista linear
encadeada custa O(1).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5 63
Ordenao Topolgica -
Implementao
Basta inserir uma chamada para o
procedimento InsLista no procedimento
BuscaDfs, logo aps o momento em que o
tempo de trmino t[u] obtido e o vrtice
pintado de preto.
Ao nal, basta retornar a lista obtida (ou
imprim-la.
procedure InsLista ( var Item: TipoItem; var Lista : TipoLista) ;
{Insere antes do primeiro item da l i st a}
var Aux: Apontador;
begin
Aux : = Lista. Primeiro^.Prox;
new( Lista. Primeiro^.Prox) ;
Lista. Primeiro^.Prox^.Item : = Item;
Lista. Primeiro^.Prox^.Prox : = Aux;
end; { Insere }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 64
Componentes Fortemente Conectados
Um componente fortemente conectado de
G = (V, A) um conjunto maximal de vrtices
C V tal que para todo par de vrtices u e v
em C, u e v so mutuamente alcanveis
Podemos particionar V em conjuntos V
i
,
1 i r, tal que vrtices u e v so
equivalentes se e somente se existe um
caminho de u a v e um caminho de v a u.
0 1
2 3
1
2
0
3 3
(a) (b)
0,1,2
(c)
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 65
Componentes Fortemente Conectados
- Algoritmo
Usa o transposto de G, denido
G
T
= (V, A
T
), onde A
T
= {(u, v) : (v, u) A},
isto , A
T
consiste das arestas de G com
suas direes invertidas.
G e G
T
possuem os mesmos componentes
fortemente conectados, isto , u e v so
mutuamente alcanveis a partir de cada um
em G se e somente se u e v so mutuamente
alcanveis a partir de cada um em G
T
.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 66
Componentes Fortemente Conectados
- Algoritmo
1. Chama BuscaEmProfundidade(G) para obter
os tempos de trmino t[u] para cada vrtice u.
2. Obtem G
T
.
3. Chama BuscaEmProfundidade(G
T
),
realizando a busca a partir do vrtice de
maior t[u] obtido na linha 1. Inicie uma nova
busca em profundidade a partir do vrtice de
maior t[u] dentre os vrtices restantes se
houver.
4. Retorne os vrtices de cada rvore da
oresta obtida como um componente
fortemente conectado separado.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 67
Componentes Fortemente Conectados
- Exemplo
A parte (b) apresenta o resultado da busca
em profundidade sobre o grafo transposto
obtido, mostrando os tempos de trmino e a
classicao das arestas.
A busca em profundidade em G
T
resulta na
oresta de rvores mostrada na parte (c).
0 1
2 3
0
2
1
3
0 1
2 3
1/8 2/7
3/6 4/5
ret
arv
arv
cruz
cruz
(c) (b) (a)
1/6 3/4
2/5 7/8
ret
arv
arv
cruz
cruz
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 68
Componentes Fortemente Conectados
- Implementao
procedure GrafoTransposto ( var Grafo : TipoGrafo; var GrafoT: TipoGrafo) ;
var v, u: TipoValorVertice;
Peso: TipoPeso;
Aux : Apontador;
begin
FGVazio(GrafoT) ;
GrafoT.NumVertices : = Grafo.NumVertices;
GrafoT.NumArestas := Grafo.NumArestas;
for v : = 0 to Grafo.NumVertices1do
i f not ListaAdjVazia(v, Grafo)
then begin
Aux : = PrimeiroListaAdj (v, Grafo) ;
FimListaAdj : = false;
while not FimListaAdj do
begin
ProxAdj (v, Grafo, u, Peso, Aux, FimListaAdj ) ;
InsereAresta(u, v, Peso, GrafoT) ;
end;
end;
end; { GrafoTransposto }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 69
Componentes Fortemente Conectados
- Implementao
O Programa BuscaEmProfundidadeCfc utiliza
a funo MaxTT para obter o vrtice de maior
t[u] dentre os vrtices restantes u ainda no
visitados por VisitaDFS.
type
TipoTempoTermino = record
t : array[ TipoValorVertice ] of TipoValorTempo;
Restantes: array[ TipoValorVertice ] of boolean;
NumRestantes: TipoValorVertice;
end;
Function MaxTT ( var TT: TipoTempoTermino) : TipoValorVertice;
var i , Temp: integer ;
begin
i :=0;
while not TT. Restantes[ i ] do i : = i + 1;
Temp : = TT. t [ i ] ; MaxTT : = i ;
for i : = 0 to Grafo.NumVertices1do
i f TT. Restantes[ i ]
then i f Temp < TT. t [ i ]
then begin Temp : = TT. t [ i ] ; MaxTT : = i ; end;
end; { MaxTT }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 70
Componentes Fortemente Conectados
- Implementao
procedure BuscaEmProfundidadeCfc ( var Grafo: TipoGrafo;
var TT: TipoTempoTermino) ;
var
Tempo : TipoValorTempo;
x, VRaiz : TipoValorVertice;
d, t : array[ TipoValorVertice ] of TipoValorTempo;
Cor : array[ TipoValorVertice ] of TipoCor;
Antecessor : array[ TipoValorVertice ] of integer ;
{Entra aqui o procedimento VisitaDFS (a seguir)}
begin
Tempo : = 0;
for x : = 0 to Grafo.NumVertices1do
begin Cor[ x] : = branco; Antecessor[ x] := 1; end;
TT.NumRestantes : = Grafo.NumVertices;
for x : = 0 to Grafo.NumVertices1do
TT. Restantes[ x] : = true;
while TT.NumRestantes > 0 do
begin
VRaiz : = MaxTT (TT) ;
writeln( Raiz da proxima arvore: ,VRaiz: 2) ;
VisitaDfs (VRaiz) ;
end;
end; { BuscaEmProfundidadeCfc }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 71
Componentes Fortemente Conectados
- Implementao
procedure VisitaDfs (u: TipoValorVertice) ;
var FimListaAdj : boolean;
Peso : TipoPeso;
Aux : Apontador;
v : TipoValorVertice;
begin
Cor[u] : = cinza; Tempo : = Tempo + 1; d[u] : = Tempo;
TT. Restantes[u] : = false ; TT.NumRestantes : = TT.NumRestantes1;
writeln( Vi si ta ,u:2, Tempo descoberta: ,d[u] : 2 , cinza ) ; readln;
i f not ListaAdjVazia(u, Grafo)
then begin
Aux : = PrimeiroListaAdj (u, Grafo) ;
FimListaAdj : = false;
while not FimListaAdj do
begin
ProxAdj (u, Grafo, v, Peso, Aux, FimListaAdj ) ;
i f Cor[ v] = branco
then begin
Antecessor[ v] : = u;
VisitaDfs(v) ;
end;
end;
end;
Cor[u] : = preto ; Tempo : = Tempo + 1; t [u] : = Tempo;
writeln( Vi si ta ,u:2, Tempo termino: , t [u] : 2 , preto ) ; readln;
end; { VisitaDfs }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6 72
Componentes Fortemente Conectados
- Anlise
Utiliza o algoritmo para busca em
profundidade duas vezes, uma em G e outra
em G
T
. Logo, a complexidade total
O(|V | +|A|).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7 73
rvore Geradora Mnima - Aplicao
Projeto de redes de comunicaes
conectando n localidades.
Arranjo de n 1 conexes, conectando duas
localidades cada.
Objetivo: dentre as possibilidades de
conexes, achar a que usa menor quantidade
de cabos.
Modelagem:
G = (V, A): grafo conectado, no
direcionado.
V : conjunto de cidades.
A: conjunto de possveis conexes
p(u, v): peso da aresta (u, v) A, custo
total de cabo para conectar u a v.
Soluo: encontrar um subconjunto T A,
acclico, que conecta todos os vrtices de G e
cujo peso total p(T) =

(u,v)T
p(u, v)
minimizado.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7 74
rvore Geradora Mnima (AGM)
Como G

= (V, T) acclico e conecta todos


os vrtices, T forma uma rvore chamada
rvore geradora de G.
O problema de obter a rvore T conhecido
como rvore geradora mnima (AGM).
Ex.: rvore geradora mnima T cujo peso total
12. T no nica, pode-se substituir a aresta
(3, 5) pela aresta (2, 5) obtendo outra rvore
geradora de custo 12.
4
1
2
5
3
5 6
(a)
4 6
2
1
(b)
4
2 2
3
1
0
3
5 4
2
1
0
3
5 4
2
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1 75
AGM - Algoritmo Genrico
Uma estratgia gulosa permite obter a AGM
adicionando uma aresta de cada vez.
Invariante: Antes de cada iterao, S um
subconjunto de uma rvore geradora mnima.
A cada passo adicionamos a S uma aresta
(u, v) que no viola o invariante. (u, v)
chamada de uma aresta segura.
procedure GenericoAGM;
1 S := ;
2 while S no constitui uma rvore geradora mnima do
3 Encontre uma aresta (u, v) que segura para S;
4 S := S + {(u, v)}
5 return S;
Dentro do while, S tem que ser um
subconjunto prprio da AGM T, e assim tem
que existir uma aresta (u, v) T tal que
(u, v) S e (u, v) seguro para S.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1 76
AGM - Denio de Corte
Um corte (V

, V V

) de um grafo no
direcionado G = (V, A) uma partio de V .
Uma aresta (u, v) A cruza o corte
(V

, V V

) se um de seus vrtices pertence
a V

e o outro vrtice pertence a V V

.
Um corte respeita um conjunto S de arestas
se no existirem arestas em S que o cruzem.
Uma aresta cruzando o corte que tenha custo
mnimo sobre todas as arestas cruzando o
corte uma aresta leve.
1
2
3
5 6
2
6 4
5 4
V
V V
V
V V
1
0
3
5 4
2
p
p
p
b b
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1 77
AGM - Teorema para reconhecer
arestas seguras
Seja G = (V, A) um grafo conectado, no
direcionado, com pesos p sobre as arestas V .
seja S um subconjunto de V que est includo
em alguma AGM para G.
Seja (V

, V V

) um corte qualquer que
respeita S.
Seja (u, v) uma aresta leve cruzando
(V

, V V

).
Satisfeitas essas condies, a aresta (u, v)
uma aresta segura para S.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2 78
AGM - Algoritmo de Prim
O algoritmo de Prim para obter uma AGM
pode ser derivado do algoritmo genrico.
O subconjunto S forma uma nica rvore, e a
aresta segura adicionada a S sempre uma
aresta de peso mnimo conectando a rvore a
um vrtice que no esteja na rvore.
A rvore comea por um vrtice qualquer (no
caso 0) e cresce at que gere todos os
vrtices em V .
A cada passo, uma aresta leve adicionada
rvore S, conectando S a um vrtice de
G
S
= (V, S).
De acordo com o teorema anterior, quando o
algoritmo termina, as arestas em S formam
uma rvore geradora mnima.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2 79
Algoritmo de Prim - Exemplo
4
1
2
5
5 6
4 6
2
3
5 6
1
(a) (b)
2 2
1
6 4
(c)
2 2
1
4
2 2
1
5 4
(f) (e)
3
2 2
1
6 4
(d)
1
0
3
4
2
5
1
0
3
4
2
5
1
0
3
4
2
5
1
0
3
4
2
5
1
0
3
4
2
5
1
0
3
4
2
4
0
0
0 0
0
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2 80
Algoritmo de Prim - Implementao
{Entramaqui os operadores de uma das implementaes para grafos}
{bem como o operador Constroi do TAD HEAP }
procedure AgmPrim ( var Grafo: TipoGrafo; var Raiz: TipoValorVertice) ;
var Antecessor : array[ TipoValorVertice ] of integer ;
p : array[ TipoValorVertice ] of TipoPeso;
Itensheap : array[ TipoValorVertice ] of boolean;
Pos : array[ TipoValorVertice ] of TipoValorVertice;
A : Vetor ;
u, v : TipovalorVertice;
procedure Refaz (Esq, Dir : Indice ; var A : Vetor ) ;
label 999;
var i : Indice ; j : integer ; x: Item;
begin
i : = Esq; j : = 2 i ; x : = A[ i ] ;
while j <= Dir do
begin
i f j < Dir
then i f p[A[ j ] .Chave] > p[A[ j + 1] .Chave] then j : = j + 1;
i f p[ x.Chave] <= p[A[ j ] .Chave] then goto 999;
A[ i ] : = A[ j ] ; Pos[A[ j ] .Chave] : = i ;
i : = j ; j : = 2 i ;
end;
999 : A[ i ] : = x; Pos[ x.Chave] : = i ;
end; { Refaz }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2 81
Algoritmo de Prim - Implementao
function RetiraMin ( var A: Vetor ) : Item;
begin
i f n < 1
then writeln( Erro: heap vazio )
else begin
RetiraMin : = A[ 1] ;
A[ 1] : = A[n] ; Pos[A[n] . chave] : = 1;
n : = n 1;
Refaz ( 1 , n, A) ;
end;
end; { Retira }
procedure DiminuiChave ( i : Indice ; ChaveNova: TipoPeso; var A: Vetor ) ;
var x: Item;
begin
i f ChaveNova > p[A[ i ] .Chave]
then writeln( Erro: ChaveNova maior que a chave atual )
else begin
p[A[ i ] .Chave] : = ChaveNova;
while ( i >1) and (p[A[ i div 2] .Chave] > p[A[ i ] .Chave] )
do begin
x : = A[ i div 2] ;
A[ i div 2] : = A[ i ] ; Pos[A[ i ] .Chave] : = i div 2;
A[ i ] : = x; Pos[ x.Chave] : = i ;
i : = i div 2;
end;
end;
end; { DiminuiChave }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2 82
Algoritmo de Prim - Implementao
begin { AgmPrim }
for u : = 0 to Grafo.NumVertices do
begin {Constroi o heap com todos os valores igual a I nf i ni t o }
Antecessor[u] := 1; p[u] : = I nf i ni t o ;
A[u+1].Chave : = u; {Heap a ser construido}
ItensHeap[u] : = true; Pos[u] : = u+1;
end;
n : = Grafo.NumVertices;
p[ Raiz] : = 0;
Constroi (A) ;
while n >= 1 do {enquanto heap nao vazio}
begin
u : = RetiraMin(A) .Chave;
i f (u <> Raiz)
then write( Aresta de arvore: v[ ,u, ] v[ ,Antecessor[u] , ] ) ; readln;
ItensHeap[u] : = false;
i f not ListaAdjVazia(u, Grafo)
then begin
Aux : = PrimeiroListaAdj (u, Grafo) ; FimListaAdj : = false;
while not FimListaAdj do
begin
ProxAdj (u, Grafo, v, Peso, Aux, FimListaAdj ) ;
i f ItensHeap[ v] and (Peso < p[ v] )
then begin
Antecessor[ v] : = u; DiminuiChave(Pos[ v] ,Peso,A) ;
end
end;
end;
end;
end; { AgmPrim }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2 83
Algoritmo de Prim - Implementao
Para realizar de forma eciente a seleo de
uma nova aresta, todos os vrtices que no
esto na AGM residem no heap A.
O heap contm os vrtices, mas a condio
do heap mantida pelo peso da aresta
atravs do arranjo p[v] (heap indireto).
Pos[v] fornece a posio do vrtice v dentro
do heap A, para que o vrtice v possa ser
acessado a um custo O(1), necessrio para a
operao DiminuiChave.
Antecessor[v] armazena o antecessor de v na
rvore.
Quando o algoritmo termina, A est vazia e a
AGM est de forma implcita como
S = {(v, Antecessor[v]) : v V {Raiz }}
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2 84
Algoritmo de Prim - Anlise
O corpo do anel while executado |V | vezes.
O procedimento Refaz tem custo O(log |V |).
Logo, o tempo total para executar a operao
retira o item com menor peso O(|V | log |V |).
O while mais interno para percorrer a lista de
adjacentes O(|A|) (soma dos comprimentos
de todas as listas de adjacncia 2|A|).
O teste para vericar se o vrtice v pertence
ao heap A tem custo O(1).
Aps testar se v pertence ao heap A e o peso
da aresta (u, v) menor do que p[v], o
antecessor de v armazenado em
Antecessor e uma operao DiminuiChave
realizada sobre o heap A na posio Pos[v], a
qual tem custo O(log |V |).
Logo, o tempo total para executar o algoritmo
de Prim
O(|V log |V | +|A| log |V |) = O(|A| log |V |).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3 85
AGM - Algoritmo de Kruskal
Pode ser derivado do algoritmo genrico.
S uma oresta e a aresta segura adicionada
a S sempre uma aresta de menor peso que
conecta dois componentes distintos.
Considera as arestas ordenadas pelo peso.
(f) (e)
(c) (d)
4
1
2
5
5 6
4 6
2
3
(a) (b)
3
1
0
3
4
2
5
1
0
3
4
2
5
1
0
3
4
2
5
1
0
3
4
2
5
1
0
3
4
2
5
1
0
4
2
5
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3 86
AGM - Algoritmo de Kruskal
Sejam C
1
e C
2
duas rvores conectadas por
(u, v):
Como (u, v) tem de ser uma aresta leve
conectando C
1
com alguma outra rvore,
(u, v) uma aresta segura para C
1
.
guloso porque, a cada passo, ele adiciona
oresta uma aresta de menor peso.
Obtm uma AGM adicionando uma aresta de
cada vez oresta e, a cada passo, usa a
aresta de menor peso que no forma ciclo.
Inicia com uma oresta de |V | rvores de um
vrtice: em |V | passos, une duas rvores at
que exista apenas uma rvore na oresta.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3 87
Algoritmo de Kruskal - Implementao
Usa la de prioridades para obter arestas em
ordem crescente de pesos.
Testa se uma dada aresta adicionada ao
conjunto soluo S forma um ciclo.
Tratar conjuntos disjuntos: maneira
eciente de vericar se uma dada aresta
forma um ciclo. Utiliza estruturas dinmicas.
Os elementos de um conjunto so
representados por um objeto. Operaes:
CriaConjunto(x): cria novo conjunto cujo
nico membro, x, seu representante.
Para que os conjuntos sejam disjuntos, x
no pode pertencer a outro conjunto.
Unio(x, y): une conjuntos dinmicos
contendo x (C
x
) e y (C
y
) em novo conjunto,
cujo representante pode ser x ou y. Como
os conjuntos na coleo devem ser
disjuntos, C
x
e C
y
so destrudos.
EncontreConjunto(x): retorna apontador
para o representante do conjunto (nico)
contendo x.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3 88
Algoritmo de Kruskal - Implementao
Primeiro renamento:
procedure Kruskal ;
1. S := ;
2. for v : = 0 to Grafo.NumVertices1do CriaConjunto ( v) ;
3. Ordena as arestas de A pelo peso;
4. for cada ( u, v) de A tomadas em ordem ascendente de peso do
5. i f EncontreConjunto (u) <> EncontreConjunto ( v)
then begin
6. S := S + {(u, v)};
7. Uniao ( u, v) ;
end;
end;
A implementao das operaes Unio e
EncontraConjunto deve ser realizada de
forma eciente.
Esse problema conhecido na literatura
como Unio-EncontraConjunto.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3 89
AGM - Anlise do Algoritmo de Kruskal
A inicializao do conjunto S tem custo O(1).
Ordenar arestas (linha 3) custa O(|A| log |A|).
A linha 2 realiza |V | operaes CriaConjunto.
O anel (linhas 4-7) realiza O(|A|) operaes
EncontreConjunto e Uniao, a um custo
O((|V | +|A|)(|V |)) onde (|V |) uma
funo que cresce lentamente ((|V |) < 4).
O limite inferior para construir uma estrutura
dinmica envolvendo m operaes
EncontreConjunto e Uniao e n operaes
CriaConjunto m(n).
Como G conectado temos que
|A| |V | 1, e assim as operaes sobre
conjuntos disjuntos custam O(|A|(|V |).
Como (|V |) = O(log |A|) = O(log |V |), o
tempo total do algoritmo de Kruskal
O(|A| log |A|).
Como |A| < |V |
2
, ento log |A| = O(log |V |), e
o custo do algoritmo de Kruskal tambm
O(|A| log |V |).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 90
Caminhos Mais Curtos - Aplicao
Um motorista procura o caminho mais curto
entre Diamantina e Ouro Preto. Possui mapa
com as distncias entre cada par de
intersees adjacentes.
Modelagem:
G = (V, A): grafo direcionado ponderado,
mapa rodovirio.
V : intersees.
A: segmentos de estrada entre
intersees
p(u, v): peso de cada aresta, distncia
entre intersees.
Peso de um caminho: p(c) =

k
i=1
p(v
i1
, v
i
)
Caminho mais curto:
(u, v) =

min

p(c) : u
c
;v

se existir caminho de u a v
caso contrrio
Caminho mais curto do vrtice u ao vrtice
v: qualquer caminho c com peso
p(c) = (u, v).
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 91
Caminhos Mais Curtos
Caminhos mais curtos a partir de uma
origem: dado um grafo ponderado
G = (V, A), desejamos obter o caminho mais
curto a partir de um dado vrtice origem
s V at cada v V .
Muitos problemas podem ser resolvidos pelo
algoritmo para o problema origem nica:
Caminhos mais curtos com destino
nico: reduzido ao problema origem nica
invertendo a direo de cada aresta do
grafo.
Caminhos mais curtos entre um par de
vrtices: o algoritmo para origem nica
a melhor opo conhecida.
Caminhos mais curtos entre todos os
pares de vrtices: resolvido aplicando o
algoritmo origem nica |V | vezes, uma vez
para cada vrtice origem.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 92
Caminhos Mais Curtos
A representao de caminhos mais curtos
pode ser realizada pela varivel Antecessor.
Para cada vrtice v V o Antecessor[v] um
outro vrtice u V ou nil (-1).
O algoritmo atribui a Antecessor os rtulos de
vrtices de uma cadeia de antecessores com
origem em v e que anda para trs ao longo de
um caminho mais curto at o vrtice origem s.
Dado um vrtice v no qual Antecessor[v] = nil ,
o procedimento ImprimeCaminho pode
imprimir o caminho mais curto de s at v.
Os valores em Antecessor[v], em um passo
intermedirio, no indicam necessariamente
caminhos mais curtos.
Entretanto, ao nal do processamento,
Antecessor contm uma rvore de caminhos
mais curtos denidos em termos dos pesos
de cada aresta de G, ao invs do nmero de
arestas.
Caminhos mais curtos no so
necessariamente nicos.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 93
rvore de caminhos mais curtos
Uma rvore de caminhos mais curtos com
raiz em u V um subgrafo direcionado
G

= (V

, A

), onde V

V e A

A, tal que:
1. V

o conjunto de vrtices alcanveis a
partir de s G,
2. G

forma uma rvore de raiz s,


3. para todos os vrtices v V

, o caminho
simples de s at v um caminho mais
curto de s at v em G.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 94
Algoritmo de Dijkstra
Mantm um conjunto S de vrtices cujos
caminhos mais curtos at um vrtice origem
j so conhecidos.
Produz uma rvore de caminhos mais curtos
de um vrtice origem s para todos os vrtices
que so alcanveis a partir de s.
Utiliza a tcnica de relaxamento:
Para cada vrtice v V o atributo p[v]
um limite superior do peso de um caminho
mais curto do vrtice origem s at v.
O vetor p[v] contm uma estimativa de um
caminho mais curto.
O primeiro passo do algoritmo inicializar os
antecessores e as estimativas de caminhos
mais curtos:
Antecessor[v] = nil para todo vrtice
v V ,
p[u] = 0, para o vrtice origem s, e
p[v] = para v V {s}.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 95
Relaxamento
O relaxamento de uma aresta (u, v) consiste
em vericar se possvel melhorar o melhor
caminho at v obtido at o momento se
passarmos por u.
Se isto acontecer, p[v] e Antecessor[v] devem
ser atualizados.
i f p[ v] > p[u] + peso da aresta ( u, v)
then p[ v] = p[u] + peso da aresta ( u, v)
Antecessor[ v] : = u
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 96
Algoritmo de Dijkstra - 1
o
Renamento
procedure Dijkstra ( Grafo, Raiz) ;
1. for v : = 0 to Grafo.NumVertices1do
2. p[ v] : = I nf i ni t o ;
3. Antecessor[ v] := 1;
4. p[ Raiz] : = 0;
5. Constroi heap no vetor A;
6 S := ;
7. While heap > 1 do
8. u : = RetiraMin(A) ;
9 S := S + u
10. for v ListaAdjacentes[u] do
11. i f p[ v] > p[u] + peso da aresta ( u, v)
12. then p[ v] = p[u] + peso da aresta ( u, v)
13. Antecessor[ v] : = u
Invariante: o nmero de elementos do heap
igual a V S no incio do anel while.
A cada iterao do while, um vrtice u
extrado do heap e adicionado ao conjunto S,
mantendo assim o invariante.
RetiraMin obtm o vrtice u com o caminho
mais curto estimado at o momento e
adiciona ao conjunto S.
No anel da linha 10, a operao de
relaxamento realizada sobre cada aresta
(u, v) adjacente ao vrtice u.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 97
Algoritmo de Dijkstra - Exemplo
6 5
10 1
2
(a)
1
3
6 5
10 1
2
1
3
(b) 0
1 10
3
6 5
10 1
2
(c)
1
3
0
1 10
6 3
1
0
4
2 3
1
0
4
2 3
1
0
4
2 3
Iterao S d[0] d[1] d[2] d[3] d[4]
(a)
(b) {0} 0 1 3 10
(c) {0, 1} 0 1 6 3 10
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 98
Algoritmo de Dijkstra - Exemplo
6 5
10 1
2
(f)
1
3
0
1 6
5 3
6 5
10 1
2
1
3
0
1 9
6 5
10 1
2
1
3
0
1 6
(d) (e)
3 5 5 3
1
0
4
2 3
1
0
4
2 3
1
0
4
2 3
Iterao S d[0] d[1] d[2] d[3] d[4]
(d) {0, 1, 3} 0 1 5 3 9
(e) {0, 1, 3, 2} 0 1 5 3 6
(f) {0, 1, 3, 2, 4} 0 1 5 3 6
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 99
Algoritmo de Dijkstra
Para realizar de forma eciente a seleo de
uma nova aresta, todos os vrtices que no
esto na rvore de caminhos mais curtos
residem no heap A baseada no campo p.
Para cada vrtice v, p[v] o caminho mais
curto obtido at o momento, de v at o vrtice
raiz.
O heap mantm os vrtices, mas a condio
do heap mantida pelo caminho mais curto
estimado at o momento atravs do arranjo
p[v], o heap indireto.
O arranjo Pos[v] fornece a posio do vrtice
v dentro do heap A, permitindo assim que o
vrtice v possa ser acessado a um custo O(1)
para a operao DiminuiChaveInd.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 100
Algoritmo de Dijkstra - Implementao
procedure Dijkstra ( var Grafo: TipoGrafo; var Raiz: TipoValorVertice) ;
var Antecessor : array[ TipoValorVertice ] of integer ;
P : array[ TipoValorVertice ] of TipoPeso;
Itensheap : array[ TipoValorVertice ] of boolean;
Pos : array[ TipoValorVertice ] of TipoValorVertice;
A : Vetor ;
u, v : TipovalorVertice;
{Entramaqui os operadores de uma das implementaes de grafos, bem
como o operador Constroi da implementao de las de prioridades, assim
como os operadores RefazInd, RetiraMinInd e DiminuiChaveInd do Progra-
ma Constroi}
begin { Dijkstra }
for u : = 0 to Grafo.NumVertices do
begin {Constroi o heap com todos os valores igual a I nf i ni t o }
Antecessor[u] := 1; p[u] : = I nf i ni t o ;
A[u+1].Chave : = u; {Heap a ser construido}
ItensHeap[u] : = true; Pos[u] : = u+1;
end;
n : = Grafo.NumVertices; {Tamanho do heap}
p[ Raiz] : = 0;
Constroi (A) ;
.
.
.
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 101
Algoritmo de Dijkstra - Implementao
.
.
.
while n >= 1 do {enquanto heap nao vazio}
begin
u : = RetiraMinInd(A) .Chave;
ItensHeap[u] : = false;
i f not ListaAdjVazia(u, Grafo)
then begin
Aux : = PrimeiroListaAdj (u, Grafo) ; FimListaAdj : = false;
while not FimListaAdj do
begin
ProxAdj (u, Grafo, v, Peso, Aux, FimListaAdj ) ;
i f p[ v] > p[u] + Peso
then begin
p[ v] : = p[u] + Peso; Antecessor[ v] : = u;
DiminuiChaveInd(Pos[ v] ,p[ v] ,A) ;
write( Caminho: v[ ,v, ] v[ ,Antecessor[ v] , ] ,
d[ ,p[ v] , ] ) ; readln;
end;
end;
end;
end;
end; { Dijkstra }
Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8 102
Porque o Algoritmo de Dijkstra
Funciona
O algoritmo usa uma estratgia gulosa:
sempre escolher o vrtice mais leve (ou o
mais perto) em V S para adicionar ao
conjunto soluo S,
O algorimo de Dijkstra sempre obtm os
caminhos mais curtos, pois cada vez que um
vrtice adicionado ao conjunto S temos que
p[u] = (Raiz, u).

Você também pode gostar