Professional Documents
Culture Documents
7 Algoritmos em Grafos
Aplicaes
Motivao
Contedo do Captulo
7.1 Definies Bsicas
Algoritmos em Grafos
Grau de um Vrtice
Grafos No Direcionados
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.
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).
Conceitos Bsicos
Grafos Direcionados
Um grafo direcionado G um par (V, A), onde V um conjunto finito
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.
0
0
aresta
1
vrtice
Notao: G = (V, A)
G: grafo
V: conjunto de vrtices
A: conjunto de arestas
11
Componentes Conectados
10
Ciclos
Em um grafo no direcionado:
Um caminho (v0 , v1 , . . . , vk ) forma um ciclo se v0 = vk e o caminho
contm pelo menos trs arestas.
Ciclos
Em um grafo direcionado:
Um caminho (v0 , v1 , . . . , vk ) forma um ciclo se v0 = vk e o caminho
contm pelo menos uma aresta.
O ciclo simples se os vrtices v1 , v2 , . . . , vk so distintos.
O self-loop um ciclo de tamanho 1.
Dois caminhos (v0 , v1 , . . . , vk ) e (v0 , v1 , . . . , vk ) formam o mesmo
ciclo se existir um inteiro j tal que vi = v(i+j) mod k para
i = 0, 1, . . . , k 1.
15
14
Subgrafos
13
Grafos Isomorfos
12
1
4
19
rvores
18
Grafos Completos
(a)
(b)
17
16
23
22
i f ( ! ListaAdjVazia(v,Grafo) )
{ Aux = PrimeiroListaAdj (v,Grafo ) ;
FimListaAdj = FALSE ;
while ( ! FimListaAdj)
ProxAdj(&v , Grafo, &u, &Peso, &Aux, &FimListaAdj ) ;
}
21
20
27
26
TipoPeso;
TipoApontador;
25
Matriz de Adjacncia
0 1 2 3 4 5
0
1
1
1
1 1
2
1 1
3 1
4
5
0 1 2 3 4 5
0
1 1
1 1
1
2 1 1
3
4
5
(a)
(b)
24
31
30
{ TipoValorVertice Result ;
TipoApontador Aux = 0;
Adj = Prox;
(Prox)++;
else Aux++;
i f (Aux == Grafo>NumVertices)
return Result ;
}
29
{ short i , j ;
{ TipoApontador Aux = 0;
28
35
34
TipoPeso Peso;
} TipoItem ;
33
5
0
1
7
1 5
1 3
}
3
3
0
5
0
1
7
1 5
0 5
{ short i , j ; p r i n t f ( "
" );
1 7
p r i n t f ( " \n" ) ;
3
p r i n t f ( " \n" ) ;
}
}
32
39
TipoValorVertice Vertice2 ,
TipoGrafo Grafo)
38
{ TipoApontador Aux;
short EncontrouAresta = FALSE ;
Aux = Aux>Prox;
return EncontrouAresta ;
37
} TipoLista ;
{ long i ;
} TipoGrafo ;
36
43
V
7
0
1
2
3
4
5
6
42
Cab
Prox
4
6
2
3
1
1
2
4
5
0
0
0
6
0
Peso
5
3
7
Cab
Prox
Peso
4
6
7
3
1
0
2
1
4
5
7
0
0
6
0
0
5
0
1
7
0
1
2
3
4
5
6
7
5
5
7
7
}
putchar( \n ) ;
}
}
41
TipoItem x ;
Grafo>Adj [ i ] . Primeiro=NULL ;
{ AuxAnterior = Aux;
Aux = Aux>Prox;
free (AuxAnterior ) ;
Grafo>NumArestas;
EncontrouAresta = TRUE ;
Grafo>NumVertices = 0;
AuxAnterior = Aux;
Aux = Aux>Prox;
}
}
40
47
46
{ TipoApontador Aux;
short EncontrouAresta = FALSE ;
TipoGrafo Grafo)
{ i f ( Vertice2 == Grafo>Cab[Aux] )
EncontrouAresta = TRUE ;
Aux = Grafo>Prox[Aux] ;
return EncontrouAresta ;
Peso = Grafo>Peso[Prox ] ;
Prox = Grafo>Prox[Prox ] ;
i f (Prox == 0) FimListaAdj = TRUE ;
}
45
{ short i ;
#define TRUE 1
#define FALSE 0
#define MAXTAM ( MAXNUMVERTICES + MAXNUMARESTAS 2)
}
}
Pos = Grafo>ProxDisponivel ;
i f ( Grafo>ProxDisponivel == MAXTAM)
Grafo>ProxDisponivel++;
TipoTam ProxDisponivel ;
Grafo>Prox[Grafo>Cab[V1] ] = Pos;
char NumVertices;
Grafo>Cab[Pos] = V2;
Grafo>Cab[V1] = Pos;
short NumArestas;
} TipoGrafo ;
typedef short TipoApontador;
44
51
Busca em Profundidade
50
Busca em Profundidade
49
48
{ short i , forlim ;
printf ( "
}
i f ( EncontrouAresta ) / Apenas marca como retirado /
p r i n t f ( "%2d%4d%4d%4d\n" , i , Grafo>Cab[ i ] ,
Grafo>Prox[ i ] , Grafo>Peso[ i ] ) ;
}
}
else p r i n t f ( "Aresta nao existe \n" ) ;
}
55
54
b( / )
b( / )
c(1/ )
b( / )
c(1/ )
c(2/ )
b( / )
b( / ) 2
b( / )
b( / ) 2
(a)
(b)
c(2/ )
c(1/ )
c(2/ )
c(1/ )
p(2/5)
b( / )
b( / )
p(3/4) 2
(d)
(e)
p(2/5)
p(1/6)
p(2/5)
p(1/6)
p(2/5)
(g)
53
c(7/ )
p(3/4) 2
p(7/8)
p(3/4) 2
(h)
(i)
{ TipoValorVertice x ;
TipoValorTempo Tempo;
TipoValorTempo d[ MAXNUMVERTICES + 1] , t [ MAXNUMVERTICES + 1];
(f)
b( / )
b( / )
p(3/4) 2
p(1/6)
p(3/4) 2
(c)
c(1/ )
c(3/ ) 2
b( / )
b( / ) 2
Tempo = 0;
i f ( ! ListaAdjVazia(&u, Grafo) )
{ Cor[ x ] = branco;
while ( ! FimListaAdj)
Antecessor[ x] = 1;
i f (Cor[ v] == branco)
{ i f (Cor[ x] == branco)
}
Cor[u] = preto ; ( Tempo)++; t [u] = (Tempo) ;
52
59
arv
ret
arv
1/10
arv
cruz
avan
3
4/5
cruz
4
7/8
cruz
arv
Classificao de Arestas
3/6
57
Classificao de Arestas
5
11/12
58
56
63
62
NArestas = NArestas 1;
i f ( NArestas > 0)
j ++;
}
i f ( NArestas == 0) GAciclico = TRUE ;
else GAciclico = FALSE ;
}
61
program GrafoAciclico ;
TipoAresta Aresta ;
TipoGrafo Grafo;
TipoArranjoArestas L;
short GAciclico ;
/ Entram aqui os operadores FFVazia, Vazia , Enfileira e
60
67
{ TipoValorVertice x ;
Apontador Aux;
TipoPeso Peso;
TipoItem Item ;
Cor[u] = cinza ;
Dist [u] = 0;
short FimListaAdj ;
TipoFila Fila ;
FFVazia(&Fila ) ;
Item . Vertice = u ;
66
{ i f (Cor[ x] == branco)
Item .Peso = 0;
Busca em Largura
Cada vrtice colorido de branco, cinza ou preto.
Todos os vrtices so inicializados branco.
65
Busca em Largura
Expande a fronteira entre vrtices descobertos e no descobertos
uniformemente atravs da largura da fronteira.
64
71
70
i f ( Antecessor[ v] == 1)
p r i n t f ( "Nao existe caminho de %d ate %d" , Origem, v ) ;
else { ImprimeCaminho(Origem,Antecessor[ v ] , Grafo , Dist , Cor, Antecessor ) ;
p r i n t f ( "%d " , v ) ;
}
}
69
b( )
b( )
4
F 0
0
(a)
c(1)
b( )
F 1 3
1 1
(b)
b( )
b( )
b( )
c(1)
b( )
b( )
p(0)
p(1)
b( )
p(0)
p(1)
b( )
c(1)
c(2)
b( )
p(1)
c(2)
b( )
u = Item . Vertice ;
i f ( ! ListaAdjVazia(&u, Grafo) )
{ Aux = PrimeiroListaAdj(&u, Grafo ) ;
F 3 2
1 2
(c)
FimListaAdj = FALSE ;
while ( FimListaAdj == FALSE)
F 2
2
(d)
p(0)
p(1)
b( )
4
F
(e)
p(0)
p(1)
c(0)
F 4
0
(f)
p(1)
p(2)
b( )
p(1)
p(2)
b( )
p(0)
p(1)
p(0)
p(0)
p(1)
p(0)
F 5
1
(g)
(h)
p(1)
p(2)
c(1)
p(1)
p(2)
p(1)
}
}
/ VisitaBfs /
68
75
74
Ordenao Topolgica
Aux = Lista>Primeiro>Prox;
Lista>Primeiro>Prox = (TipoApontador)malloc(sizeof( tipoCelula ) ) ;
Lista>Primeiro>Prox>Item = Item ;
Lista>Primeiro>Prox>Prox = Aux;
}
73
Ordenao Topolgica
Ordenao Topolgica
16/17
4/5 3
19/20
7/12
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.
6/13
8/11
2/15
3/14
9/10
72
79
1/6
0
cruz
3
4/5
2
3/6
(a)
ret
arv
cruz
arv cruz
1
arv
3
2
cruz
7/8
2/5
(b)
3/4
ret
78
1/8
2
arv
1
(c)
77
76
0,1,2
(a)
(b)
(c)
83
82
{ TipoValorTempo Tempo;
TipoValorTempo d, TipoValorTempo t ,
TipoValorVertice v ;
Cor[u] = cinza ;
TT>Restantes[u] = FALSE ;
TT>NumRestantes ;
TT>NumRestantes = Grafo>NumVertices;
getchar ( ) ;
d, t ,Cor, Antecessor ) ;
}
}
81
{ TipoValorVertice v , Adj ;
TipoPeso Peso;
TipoValorVertice NumRestantes;
TipoApontador Aux;
} TipoTempoTermino;
FGVazio(GrafoT) ;
GrafoT>NumArestas = Grafo>NumArestas;
GrafoT>NumVertices = Grafo>NumVertices;
{ i f ( ! ListaAdjVazia(&v , Grafo) )
FimListaAdj = FALSE ;
while ( ! FimListaAdj)
{ i f ( TT>Restantes[ i ] )
}
}
}
}
return Result ;
}
}
}
80
87
86
Modelagem:
G = (V, A): grafo conectado, no direcionado.
V : conjunto de cidades.
6
1
5
3
2
5
4
p(u, v): peso da aresta (u, v) A, custo total de cabo para conectar
u a v.
2
4
(a)
(b)
85
84
91
90
89
1{ S = ;
{ ( u, v ) = seleciona(A) ;
p
V
V V
5
2
p
3
V V
2
4
b
6 4
5
3
4
5
88
95
94
{ TipoItem Result ;
{ TipoItem x ;
Pos[A[n ] .Chave] = 1 ; n;
return ;
RefazInd(1 , n, A, P, Pos ) ;
return Result ;
93
92
(b)
0
5
1
(d)
A[ i ] = A[ j ] ; Pos[A[ j ] .Chave] = i ; i = j ;
2
1
5
2
1
Pos[ x .Chave] = i ;
}
(f)
2
1
2
1
2
1
4
2
1
6
j = i 2;
L999: A[ i ] = x ;
(e)
2
1
2
1
{ i f ( j < Dir )
{ i f (P[A[ j ] .Chave] > P[A[ j +1].Chave] ) j ++; }
0
0
(c)
0
0
2
1
5
99
98
Logo, o tempo total para executar a operao retira o item com menor
peso O(|V | log |V |).
97
i f (u != Raiz)
{ int
Vetor A;
FimListaAdj = FALSE ;
while ( ! FimListaAdj)
TipoItem TEMP;
A[u+1].Chave = u ;
}
}
}
}
{ Antecessor[ v ] = u;
96
103
void Kruskal ( ) ;
{
1. S = ;
6.
{ S = S+ { (u, v ) } ;
7.
Uniao ( u, v ) ;
}
102
Primeiro refinamento:
5.
101
100
(b)
0
(c)
0
5
3
2
5
3
2
(d)
(e)
0
2
5
(f)
2
4
6
4
2
5
107
106
105
Pk
i=1 p(vi1 , vi )
n
o
c
min p(c) : u ;
v
se existir caminho de u a v
caso contrrio
104
111
{
1. for (v=0;v < Grafo.NumVertices; v++)
p[ v ] = I n f i n i t o ;
3.
Antecessor[ v] = 1;
110
Relaxamento
2.
4. p[Raiz] = 0;
i f (p[ v] > p[u] + peso da aresta ( u, v) )
6. S = ;
Antecessor[ v ] = u ; }
u = RetiraMin(A) ;
9.
S = S + u;
12.
p[ v ] = p[u ]
13.
Antecessor[ v ] = u;
Algoritmo de Dijkstra
Mantm um conjunto S de vrtices cujos caminhos mais curtos at um
vrtice origem j so conhecidos.
109
108
115
Algoritmo de Dijkstra
(a)
(b)
(b)
10
4
3
1
5
2
6
2
(d)
1
1
1
2
5
2
10
Iterao
d[0]
d[1]
(a)
(b)
{0}
(c)
{0, 1}
6
2
3
1
3
3
0
0
10
6
2
6
4
6
2
(f)
10
4
10
10
0
1
10
Iterao
d[0]
d[1]
d[2]
d[3]
d[4]
(d)
{0, 1, 3}
(e)
{0, 1, 3, 2}
(f)
{0, 1, 3, 2, 4}
1
1
10
1
2
6
4
6
2
d[2]
d[3]
d[4]
10
10
10
4
10
10
0
1
(f)
10
10
(e)
(c)
0
1
10
(e)
10
(c)
0
1
113
6
2
(d)
1
2
10
(a)
114
112
119
1
11
00
00
11
00
11
00
11
0
1
00
11
3
0
1
00
11
0
1
0
1
0
1
0
1
5
0
1
h0 (x)
Arestas
h1 (x)
1
0
0 (1, 3, 5, 8)
1
(1, 2, 4, 7)
(0, 2, 5, 9)
h2 (x)
117
i f ( ! ListaAdjVazia(&u, Grafo) )
/ Entram aqui os operadores de uma das implementaes de grafos, bem como o operador Constroi da implementao de filas de prioridades, assim como os operadores RefazInd, RetiraMinInd e DiminuiChaveInd do Programa Constroi /
void Dijkstra (TipoGrafo Grafo , TipoValorVertice Raiz)
while ( ! FimListaAdj)
DiminuiChaveInd(Pos[ v ] , P[ v ] , A, P, Pos) ;
A[u+1].Chave = u ;
}
}
}
}
118
}
n = Grafo>NumVertices;
P[(Raiz) ] = 0 ;
Constroi(A, P, Pos) ;
116
123
122
0 1 2
9
0
1 7 8
9
2 7
8
3
4 7
8 9
5
121
120
127
TipoValorAresta NumAresta,
TipoGrafo Grafo)
Tipor v = 0;
return Aux;
}
126
125
124
131
{ TipoApontador ArestaAtual = 0;
{ int i , j ; p r i n t f ( "
130
" );
p r i n t f ( " \n" ) ;
{ p r i n t f ( "%3d" , i ) ;
p r i n t f ( "%3d" , Grafo>Mat[ i ] [ j ] ) ;
return Resultado;
p r i n t f ( " \n" ) ;
{ Inc = Prox;
Prox = Prox + 1;
while (Prox < Grafo>NumArestas && Grafo>Mat[ Vertice ] [ Prox] == 0) Prox = Prox + 1;
return ListaVazia ;
129
{ TipoValorAresta ArestaAtual = 0;
{ int i ;
i f ( Grafo>ProxDisponivel == MAXNUMARESTAS)
else
{ EncontrouAresta = TRUE ;
Grafo>ProxDisponivel = Grafo>ProxDisponivel + 1;
}
}
short ExisteAresta ( TipoAresta Aresta , TipoGrafo Grafo)
{ TipoValorAresta ArestaAtual = 0;
short EncontrouAresta = FALSE ;
return Aresta ;
EncontrouAresta == FALSE)
{ EncontrouAresta =
ArestasIguais(&(Aresta>Vertices ) , ArestaAtual , Grafo ) ;
ArestaAtual = ArestaAtual + 1;
}
return EncontrouAresta;
}
128
135
134
133
132
1
11
00
00
11
00
11
00
11
0
1
00
11
3
0
1
00
11
0
1
0
1
0
1
0
1
5
0
1
h0 (x)
Arestas
h1 (x)
1
0
0 (1, 3, 5, 8)
1
0
1
2
Arestas
|A|=3 (1,2,4) (1,3,5) (0,2,5)
(1, 2, 4, 7)
(0, 2, 5, 9)
h2 (x)
(a)
Prim 0
|V|=3 2
1
1
0 1
Prox
r|A|=3x3=9 1 0
2
5
3
4
4
6
5
8
2 3 4 5 6 7 8
1 1 1 3 1 1 7
(b)
139
138
TipoArranjoArestas Arestas ;
TipoValorVertice Prim[ MAXNUMARESTAS + 1];
TipoValorAresta NumArestas;
TipoMaxTamProx ProxDisponivel ;
TipoValorVertice NumVertices;
Tipor r ;
} TipoGrafo ;
typedef int TipoApontador;
137
136
143
142
TipoGrafo Grafo)
{ Tipor v ;
{ Prev = INDEFINIDO ;
TipoValorAresta A1;
int Aux;
A1 = Aux % Grafo>NumArestas;
short EncontrouAresta ;
EncontrouAresta = FALSE ;
{ Prev = Aux;
Aux = Grafo>Prox[Aux] ;
A1 = Aux % Grafo>NumArestas;
{ A1 = Aux % Grafo>NumArestas;
i f (Aux >= 0)
{ i f ( Prev == INDEFINIDO ) Grafo>Prim[ Aresta>Vertices [ v ] ] = Grafo>Prox[Aux] ;
EncontrouAresta = TRUE ;
Aux = Grafo>Prox[Aux] ;
return EncontrouAresta ;
return Resultado;
}
141
{ int i , Ind ;
i f ( Grafo>ProxDisponivel == MAXNUMARESTAS + 1)
{ Tipor i = 0 , j ;
else
{ j = 0;
while ( (V1[ i ] ! = Grafo>Arestas[NumAresta] . Vertices [ j ]) &&
Grafo>Prox[ Ind ] =
i ++;
return Aux;
}
void FGVazio(TipoGrafo Grafo)
{ int i ;
Grafo>ProxDisponivel = 0;
for ( i = 0; i < Grafo>NumVertices ; i ++) Grafo>Prim[ i ] = 1;
}
140
147
int main( ) {
TipoApontador Ap;
getchar ( ) ;
int i , j ;
TipoValorAresta Inc ;
TipoValorVertice V1;
TipoAresta Aresta ;
TipoPesoAresta Peso;
TipoGrafo Grafo;
short FimListaInc ;
ImprimeGrafo(&Grafo ) ;
getchar ( ) ;
getchar ( ) ;
FGVazio (&Grafo ) ;
145
{ int i , j ;
TipoGrafo Grafo)
TipoGrafo Grafo)
{ p r i n t f ( "%2d" , i ) ;
short FimListaInc )
j = Grafo>Prim[ i ] ;
while ( j ! = INDEFINIDO)
{ p r i n t f ( "%3d" , j % Grafo>NumArestas) ;
j = Grafo>Prox[ j ] ;
i f ( Grafo>Prox[Prox] == INDEFINIDO)
FimListaInc = TRUE ;
p r i n t f ( " \n" ) ;
146
}
}
144
149
i f ( ExisteAresta(&Aresta, &Grafo) )
{ Ap = PrimeiroListaInc(&V1, &Grafo ) ;
p r i n t f ( "Sim\n" ) ;
FimListaInc = FALSE ;
else p r i n t f ( "Nao\n" ) ;
while ( ! FimListaInc )
getchar ( ) ;
i f ( ExisteAresta(&Aresta, &Grafo) )
{ Aresta = RetiraAresta(&Aresta, &Grafo ) ;
p r i n t f ( "Aresta retirada : " ) ;
for ( i = 0; i < Grafo. r ; i ++) p r i n t f ( "%3d" , Aresta . Vertices [ i ] ) ;
p r i n t f ( "%4d\n" , Aresta .Peso) ;
}
else p r i n t f ( "Aresta nao existe \n" ) ;
ImprimeGrafo(&Grafo ) ;
return 0;
}
148