Sei sulla pagina 1di 22

Esempi di grafi

Algoritmi e Strutture Dati


Capitolo 9 - Grafi

Alberto Montresor
Universit di Trento

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License. To view a
copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/ or send a letter to Creative
Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.

Alberto Montresor 1 Alberto Montresor 2

Problemi sui grafi Grafi orientati e non orientati: definizione

Visite Un grafo orientato G una coppia Un grafo non orientato G una


Visite in ampiezza (numero di Erds) (V, E) dove: coppia (V, E) dove:
Insieme finito dei vertici V Insieme finito dei vertici V
Visite in profondit (ordinamento topologico, componenti (fortemente) connesse)
Insieme degli archi E: relazione Insieme degli archi E:
Cammini minimi binaria tra vertici coppie non ordinate
Da singola sorgente
Fra tutte le coppie di vertici 2 2
3 3
Alberi di connessione minimi 1 A
1

Problemi di flusso 6 6
.... 4 4 5
5

V = {1, 2, 3, 4, 5, 6 } V = {1, 2, 3, 4, 5, 6 }
E = { (1,2), (1,4), (2,3), (4,3), E = { [1,2], [1,4], [2,3], [3,4],
Alberto Montresor 3 (5,3), (4,5), (4,1) }
Alberto Montresor
[3,5], [4,5] } 4
oi ad inventarne una fittizia.
discuteremo
Definizioni:dei principali
incidenza approcci per realizzare la struttura di
e adiacenza Rappresentazione grafi
otesi semplificativa che linsieme statico degli n nodi possa essere
1 a n.InPer
un eseguire unoperazione su tutti i nodi e su tutti gli archi,
grafo orientato Poniamo
each come un segue:
arco (u,v) si dice incidente da u in v n = |V| numero di nodi

In un grafo non orientato


m = |E| numero di archi

la relazione di incidenza tra vertici simmetrica



Matrice di adiacenza
) do

e sullarco (u, v)
Un vertice v si dice adiacente a u
Spazio richiesto O(n2)
se e solo se (u, v) E
(1,2) incidente da 1 a 2
(1,4) incidente da 1 a 4
Verificare se il vertice u adiacente a v richiede tempo O(1)
(4,1) incidente da 4 a 1 Elencare tutti gli archi costa O(n2)
utti i nodi del grafo,
2 mentre il secondo scorre tutti i nodi adiacenti
azione. Per semplificare il testo3inoltre, useremo il termine
2 adiacente ad 1G.n
Liste / vettori di adiacenza
1
).size(). 3 adiacente a 2, 4, 5 Spazio richiesto O(n+m)
1 adiacente a 4 e viceversa Verificare se il vertice u adiacente a v richiede tempo O(n)
6 2 non adiacente a 3,4
on matrici 4
6 non adiacente ad alcun vertice Elencare tutti gli archi costa O(n+m)
5
ici per rappresentare un grafo e` basata su matrici. Dato un grafo
Alberto Montresor 5 Alberto Montresor 6

diacenza M = [muv ] (detta anche matrice di adiacenza nodi-nodi)


Matrice di adiacenza: grafo orientato o non orientato Liste di adiacenza: grafo orientato
n n, tale che:

1, se (u, v) E, Spazio: n2 G.adj(u) = { v | (u,v) E } Spazio: an + bm


muv =
0, se (u, v)
/ E.
1 2 3 4 5 6 a b
to, la matrice e` simmetrica, ovvero muv = mvu 1 per0 ogni 1 u,0v. Un
1 0 0 1 2 4 nil
nza e` mostrata nella Fig. 9.6.
2 0 0 1 0 0 0 2 3 nil
e e` banale verificare
2
in tempo O(1) se un dato arco e` presente nel 2
il tempo per ricavare linsieme di 3 adiacenza G. 3 adj0(u) 0di un 0 qual-
0 1 0 3 3 4 nil

, indipendentemente
1 dalla cardinalit`a di G.adj4(u), 1perch0 e occorre
1 0 0 0 1 4 1 5 nil

matrice alla ricerca degli elementi muv = 1. Inoltre, lo spazio 5 3 nil


6 5 0 0 0 1 0 0 6
n2 ) e il tempo per esaminare tutti gli archi e` (n2 ), anche se il 6 nil
ene un numero m 4 di archi che e` O(n).
5 6
Se il grafo 0e` pesato,
0 0 allora
0 0 0 4 5
o i pesi degli archi al posto degli elementi binari. Se puv e` il peso
trice M diventa:
Alberto Montresor 7 Alberto Montresor 8
i [j + 1, ultimo] : A[i] A[j]
Vettore di adiacenza: grafo orientato foreach u G.V() do Matrice di adiacenza: grafo non orientato
foreach v G.adj(u) do
(u, v)
fai unoperazione sullarco
G.adj(u) = { v | (u,v) E } Spazio: an + bm 1, se [u, v] E, Spazio: n2 o n(n+1)/2
muv =
0, se [u, v]
/ E.
a b Il primo foreach scorre tutti i nodi del grafo, mentre il secondo scorre tutti i nodi
1 adiacenti
2 3 4 5 6
al nodo u preso in considerazione. Per semplificare il testo inoltre, useremo il termine G.n
1 0 1 0 1 0 0
1 2 4 come abbreviazione di G.V().size().
2 2 2 1 0 1 0 0 0
3 3
2 9.3 Realizzazioni
A
con matrici 0 1 0 1 1 0
3 3 4 1 3
1 4 1 5 Uno dei modi pi`u semplici per rappresentare un grafo e` basata su matrici.
4 Dato1 un0 grafo1 0 1 0
5
G = (V, E), la matrice di adiacenza M = [muv ] (detta anche matrice 6 di adiacenza nodi-nodi)
5 3 5 0 0 1 1 0 0
6 e` una matrice di dimensione n n, tale4 che:
6 nil
5
6 0 0 0 0 0 0
4 5 1, se (u, v) E,
muv =
0, se (u, v)
/ E.

Se il grafo non e` orientato, la matrice e` simmetrica, ovvero muv = mvu per ogni u, v. Un
Alberto Montresor
esempio di matrice 9 di adiacenza
Alberto Montresor
e` mostrata nella Fig. 9.6. 10
Con questa realizzazione e` banale verificare in tempo O(1) se un dato arco e` presente nel
Liste/vettore di adiacenza: grafo non orientato grafo oppure no. Purtroppo, Grafi pesati per ricavare linsieme di adiacenza G.adj(u) di un qual-
il tempo
siasi nodo u e` sempre (n), indipendentemente dalla cardinalit`a di G.adj(u), perche occorre
scandire unintera riga della
In alcunimatricecasi allaogni
ricerca degli
arco elementi
ha un muv =
peso (costo, 1. Inoltre,associato
guadagno) lo spazio
G.adj(u) = { v | [u,v] E or [v,u] E} Spazio: an + di
2bm
memoria occupato e` (n ) e il tempo per esaminare tutti gli archi e` (n ), anche se il
2 2
a b Il peso pu essere determinato tramite una funzione di costo
grafo e` sparso, ovvero contiene un numero m di archi che e` O(n). Se il grafo e` pesato, allora
p: V V R, dove R linsieme dei numeri reali
a b nella matrice M si utilizzano i pesi degli archi al posto degli elementi binari. Se puv e` il peso
Quando tra due vertici non esiste un arco, il peso infinito
dellarco (u, v), allora la matrice M diventa:
1 2 4 nil
2 puv , se (u, v) E, 1 2 3 4 5 6
2 1 3 nil muv =
3
+ (oppure ) se (u, v) / E. * 3 * 1 * *
A
1 3 2 4 5 nil 1
4 1 3 5 nil 2 3 * 4 * * *
6
5 3 4
4
nil
3 2 3 * 4 * 4 7 *
4 5 3
6 nil 4 1 * 4 * 8 *
1
4 5
1 7 6 * * 7 8 * *

8 6 * * * * * *
4 5
Alberto Montresor 11 Alberto Montresor 12
prevedono la possibilit`a di inserire o cancellare nodi o archi, di ottenere linsieme di tutti i nodi
Specifica
o dei nodi adiacenti ad un particolare nodo. Definizioni: Grado
Infine, la situazione pu`o essere ulteriormente complicata dal fatto che in molte applicazioni
ulteriori
G RAPH
informazioni (dette etichette, o pesi) sono associate ai nodi e/o agli archi. In tal caso, In un grafo non orientato

si parla di grafi etichettati (o pesati), i quali richiedono ulteriori operatori, per reperire e/o il grado di un vertice il numero di archi che partono da esso
Graph( ) % Crea un grafo vuoto
modificare le informazioni associate a nodi e/o archi. Non e` quindi un caso che nelle librerie
insertNode(N ODE u) % Aggiunge il nodo u al grafo
dei pi`u diffusi linguaggi di programmazione siano disponibili numerose realizzazioni per leIn un grafo orientato
insertEdge(N ODE u, N ODE v) % Aggiunge larco (u, v) al grafo
strutture di dati insieme, dizionario, etc., ma che non vi sia una realizzazione standard per i il grado entrante (uscente) di un vertice il numero di archi incidenti in (da) esso
(N ODE u) % Rimuove il nodo u dal grafo
grafi. deleteNode
Non staremo quindi noi ad inventarne una fittizia.
deleteEdge (N ODEsezioni
u, N ODEdiscuteremo
v) % Rimuove larco (u, nel grafo
v) realizzare in : 1
Nelle prossime dei principali approcci per la struttura di in : 2
in : 1 out: 1 out: 1
S ET adj(N ODE u) % Restituisce linsieme dei nodi adiacenti ad
dati grafo. Partiremo dallipotesi semplificativa che linsieme statico degli n nodi possa essere
u 2 2
2 3 out: 2 3
S ET V() dai numeri da 1 a n. Per eseguire%unoperazione
rappresentato su tutti
Restituisce linsieme i nodi
di tutti i nodie su tutti gli archi,
A1 3 1
utilizzeremo il costrutto foreach come segue:
2
Di tutte u
queste sole procedure adj() e V();
Complessit in : 1
foreach G.procedure,
V() do discuteremo la realizzazione delle

il motivo principale e` che, in questo testo, i grafi sono usati per rappresentare relazioni tra out: 1
foreach v G.adj(u) do O(n+m) liste di adiacenza
oggetti che non mutano nel tempo. In altri termini, non si effettuano mai ne cancellazioni ne 4 5 2 4 5
(u, v) 3
inserzioni, fai
ne diunoperazione
nodi ne di archi, sullarco
ma si esplorano sistematicamente
grafi
2 forniti in ingresso, al
O(n ) matrice di adiacenza
in : 2
fine di determinarne sottoinsiemi di nodi e/o di archi che soddisfino certe propriet`a. out: 2 in : 0
Qualora il grafo sia dinamico, la struttura di dati pi`u adatta O(m)
operazioni
per rappresentarlo dipende 6 6
0 out: 0
Il primo
dalla particolare
Alberto Montresor
foreach scorre del
utilizzazione tutti i nodi
grafo delRealizzazioni
stesso. grafo, mentre il secondo
efficienti scorre
di insiemi tutti i nodi 13adiacenti
e dizionari
Alberto Montresor 14
sono state
al nodo u presotrattatein
ampiamente nei capitoliPer
considerazione. precedenti, ed il lettore
semplificare pu`o cercare
il testo inoltre,di useremo
combinar- il termine G.n
le per esercizio in modo da fornire realizzazioni efficienti per le operazioni di inserzione e
Definizioni:
come abbreviazione Cammini
cancellazione di nodi e/o archi.
di G.V().size(). Definizioni: Cicli
Inoltre, nella vita di un programmatore capita di lavorare con i grafi senza menzionarli
In un grafo orientato
esplicitamente. Ad esempio,G=(V,E)
un file system pu`o essere visto come un albero di directory e file, In un grafo orientato G=(V,E)
9.3ma laRealizzazioni con matrici
presenza di hard link e symbolic link fanno s` che lalbero sia in realt`a un grafo. Le ope-
un cammino di lunghezza k una sequenza di vertici u , u , ..., u tale che un ciclo di lunghezza k un cammino u , u , ..., u tale che
0 1 k 0 1 k
razioni per la creazione di nodi e archi sono quindi condizionate dalla particolare semantica
Uno dei
associata
(u i, u ) E
modiepi`
i+1
al grafo,
per 0 i
u semplici
parleremo
k1
per rappresentare
di creazione di file al posto un grafo e` dibasata
di creazione nodi. su matrici. Dato un grafo
(u i, u i+1) E per 0 i k1, u 0 = u k, e k>2
G = (V, E), la matrice di adiacenza M = [muv ] (detta anche matrice di adiacenza nodi-nodi)
In un grafo non orientato G=(V,E) In un grafo non orientato G=(V,E)
e` una matrice di dimensione n n, tale che:
una catena di lunghezza k una sequenza di vertici u0, u1, ..., uk tale che un circuito di lunghezza k una catena u0, u1, ..., uk tale che
[ui, ui+1] E per 0 i k1 1, se (u, v) E, [ui, ui+1] E per 0 i k1, u0 = uk, e k>2
muv =
0, Esempio:
se (u, v)1,
/ 2,E.3, 5, 4 una Esempio: 1, 2, 3, 5, 4, 1 un
2
3 catena nel grafo con lunghezza 4 2 circuito con lunghezza 5
Se il grafo non e` orientato, la matrice e` simmetrica, ovvero muv = mvu per ogni u, v. Un 3
1
esempio di matrice di adiacenza e` mostrata nella Un Fig. 9.6. (catena) si dice semplice
cammino 1 Un ciclo (circuito) si dice semplice se
Con questa realizzazione e` banale verificare se tutti i suoi O(1)
in tempo verticisesono distinti
un dato arco e` presente nel tutti i suoi vertici sono distinti
(compaiono una sola volta nella (tranne ovviamente il primo / lultimo)
grafo oppure no. Purtroppo, il tempo per ricavare linsieme di adiacenza G.adj(u) di un qual-
4 sequenza)
siasi nodo u e` sempre (n), indipendentemente
5 dalla cardinalit`a di G.adj(u), perche occorre 4 5
scandire unintera riga della matrice alla ricerca degli elementi muv = 1. Inoltre, lo spazio
di memoria occupato e` (n2 ) e il tempo per esaminare tutti gli archi e` (n2 ), anche 15
se il 16
Alberto Montresor Alberto Montresor
Definizioni: Grafi aciclici Definizioni: Grafo completo

Un grafo senza cicli detto aciclico Un grafo completo un grafo che ha un arco tra ogni coppia di vertici.

2 Questo grafo completo


3 Un grafo orientato aciclico
chiamato DAG (Directed
1 Acyclic Graph)
Questo grafo 2
aciclico 6 3
Questo grafo non completo
2 1
4 5 3
1 2
3
2 6
1 4 5
3
1 4
Questo grafo non 5
aciclico 6 n
X1
4
n(n 1)
5 m= i=
i=1
2
4 5

Alberto Montresor 17 Alberto Montresor 18

Definizioni: Alberi Definizioni: Alberi di copertura

Un albero libero un grafo non orientato connesso, aciclico In un grafo non orientato G=(V, E)
Se qualche vertice detto radice, otteniamo un albero radicato
un albero di copertura T un albero libero T = (V, E) composto da tutti i nodi di V
e da un sottoinsieme degli archi (E E), tale per cui tutte le coppie di nodi del
Un insieme di alberi detta foresta grafo sono connesse da una sola catena nellalbero.
rad
ice

2 2 2
3 3 3
1 1 1
6 6 6

4 5 4 5 4 5

8 9
Alberto Montresor 19 Alberto Montresor 20
Un esempio di utilizzo dei grafi Un esempio di9.utilizzo
CAPITOLO GRAFI dei grafi 149

Sherlock Holmes indaga sulla morte del duca McPollock, ucciso da unesplosione nel suo maniero: F E
Watson: Ci sono novit, Holmes: pare che il testamento, andato distrutto nellesplosione, fosse
stato favorevole ad una delle sette amiche del duca H B C

Holmes: Ci che pi strano, che la bomba sia stata fabbricata appositamente per essere nascosta G A
nellarmatura della camera da letto, il che fa supporre che lassassino abbia necessariamente fatto
a)
pi di una visita al castello
Watson: Ho interrogato personalmente le sette donne, ma ciascuna ha giurato di essere stata nel
A H B
castello una sola volta nella sua vita. H B
G B
(1) Ann ha incontrato Betty, Charlotte, Felicia e Georgia; ?
G A ? G A
(2) Betty ha incontrato Ann, Charlotte, Edith, Felicia e Helen; H
(3) Charlotte ha incontrato Ann, Betty e Edith; b)
(4) Edith ha incontrato Betty, Charlotte, Felicia;
(5) Felicia ha incontrato Ann, Betty, Edith, Helen; B
H E
(6) Georgia ha incontrato Ann e Helen;
(7) Helen ha incontrato Betty, Felicia e Georgia.
G F C
Vedete, Holmes, che le testimonianze concordano. Ma chi sar lassassino?
c)
Holmes: Elementare, Watson: ci che mi avete detto individua inequivocabilmente lassassino!
Alberto Montresor 21 Figura
Alberto Montresor 9.5: a) Il grafo degli incontri. b) Rappresentazione di circuiti di lunghezza 4 come intersezione di 22
intervalli della retta. c) Possibili periodi di soggiorno al castello cancellando il nodo A.
Problema: Visita grafi Visita: attenzione alle soluzioni facili
Watson: Ho interrogato personalmente le sette donne, ma ciascuna ha giurato di essere stata
nel castello una sola volta nella sua vita. Dagli interrogatori risulta che:
Definizione del problema Prendere ispirazione dalla visita degli alberi
(1) Ann ha incontrato Betty, Charlotte, Felicia e Georgia;
Dato un grafo G=(V, E) ed un vertice r di V (detto sorgente o radice), Ad esempio:
(2) Betty ha incontrato Ann, Charlotte, Edith, Felicia e Helen;
visitare ogni vertice raggiungibile nel grafo a partire dal vertice r (3) Charlotte ha incontrato Ann, Betty e Edith;
6 utilizziamo

(4) Edith hauna visita Betty,
incontrato BFS Charlotte,
basata suFelicia;
coda Algoritmi e Strut
Ogni nodo deve essere visitato una volta sola (5) Felicia ha incontrato Ann, Betty, Edith,
trattiamo i vertici adiacenti come seHelen;
fossero i figli
(6) Georgia ha incontrato Ann e Helen;
Visita in ampiezza (breadth-first search) (7) Helen ha incontrato Betty, Felicia e Georgia.
Visita i nodi espandendo la frontiera fra nodi scoperti / da scoprire visita (GHolmes,
Vedete, RAPH G,che N ODE r)
le testimonianze concordano. Ma chi sar`a lassassino?
Esempi: Cammini pi brevi da singola sorgente Q UEUE
Holmes: S
Elementare, mio caro()
Queue Watson: ci`o che mi avete detto individua inequivocabilmente
S.enqueue(r)
lassassino!

to
Visita in profondit (depth-first search) while not
Soluzione S.isEmpty
di Holmes: () do
Il grafo degli incontri tra le donne, indicate con le loro iniziali, e`

lia
Visita i nodi andando il pi lontano possibile nel grafo disegnatoN ODE
nella ogni donna()
Sedequeue
Fig.u9.5a).S. avesse detto la verit`a, questo grafo dovrebbe rappre-

Esempi: Componenti fortemente connesse, ordinamento topologico ag


sentare lintersezione di 7 intervalli della retta reale (un grafo siffatto si dice grafo di intervalli).
{ esamina il nodo u }
In tal caso, per`o, ogni circuito di lunghezza maggiore o uguale a 4 dovrebbe possedere un arco
Sb
foreach v G.adj(u) do
S.enqueue(v)

Alberto Montresor 23 Alberto Montresor 24


Esempio di visita - errata Esempio di visita - errata

r r u = 6
6 6

2 2
3 9 3 9
1 1
11 11

4 5 4 5
10 10
8 8

7 7

Coda:{6} Coda:{2,4,9}

Alberto Montresor 25 Alberto Montresor 26

Esempio di visita - errata Esempio di visita - errata

r u = 2 r u = 4
6 6

2 2
3 9 3 9
1 1
11 11

4 5 4 5
10 10
8 8

7 7 u Nodi gi visitati:
u Marcare un nodo visitato in modo che
Coda:{4,9,3,1,6} Coda:{9,3,1,6,5,6,1,3} non possa essere visitato di nuovo
u Bit di marcatura: nel vertice, array
separato, etc.

Alberto Montresor 27 Alberto Montresor 28


Algoritmo generico per
Genericamente, la visita
la visita di un grafo pu`o essere descritta dalla procedura visita(). Visita in ampiezza (breadth first search, BFS)

visita(G RAPH G, N ODE r) l


S l'insieme frontiera Cosa vogliamo fare?

S ET S Set() l Il funzionamento di Visitare i nodi a distanze crescenti dalla sorgente

S.insert(r) insert() e remove() visitare i nodi a distanza k prima di visitare i nodi a distanza k+1

{ marca il nodo r come scoperto } non specificato


Generare un albero BF (breadth-first)
while S.size() > 0 do
CAPITOLO 9. GRAFI 155
N ODE u S.remove() albero contenente tutti i vertici raggiungibili da r e tale che il cammino da r

{ esamina il nodo u } ad un nodo nell'albero corrisponde al cammino pi breve nel grafo


9.5.1 foreach Visitav BFS G.adj(u) do Calcolare la distanza minima da s a tutti i vertici raggiungibili
{ esamina larco (u, v) }
Nella visita BFS, i nodi sono visitati in ordine di distanza crescente dal nodo di partenza r,
numero di archi attraversati per andare da r ad un vertice
if v non e` gi`a stato scoperto then
dove la distanza{ da r adilunnodo
marca generico nodo
v come u e` il minimo
scoperto } numero di archi in un cammino da r
a u. Tale metodo S.di visita e` unestensione di una visita per livelli di un albero radicato, in cui i
insert(v)
figli di un nodo sono visitati dopo aver visitato tutti gli altri nodi che stanno allo stesso livello
del padre.
Poiche la BFS visita i nodi pi`u vicini ad r prima di quelli lontani, linsieme S e` una co-
Linsieme
da Montresor
(con politica S contiene
di rimozionei nodiFIFO).
che sono stati scoperti,
Il processo ma non e`ancora
di marcatura visitati.
realizzato con29I un
nodi vengono
vettore di 30
Alberto Alberto Montresor

estratti da S uno dopo laltro per essere visitati, e nel contempo si


booleani; la posizione corrispondente al nodo u viene inizializzata a false, per diventare trueesaminano tutti gli archi
uscenti
Visita
quando indal nodoviene
ilampiezza
nodo visitato
(breadth per scoprire
first
scoperto search,nuovi
duranteBFS) nodi. Grazie al controllo effettuato nel costrutto
la visita. Applicazione if, BFS: Numero di Erds
ogni nodo del grafo e` inserito nellinsieme S una sola volta; poiche per ogni nodo v, linsieme
l Insieme S gestito
G.bfs (v)RAPH
adj(G vieneG,scandito
N ODE r) una sola volta, questo algoritmo tramite e` ottimo ha complessit`a (nPaul
unae coda + m). Erds (1913-1996)
Nel Q caso
UEUE di S
grafi
orientati
Queue( )e fortemente connessi, o non orientati e connessi, la visita parte da
Matematico

un generico nodo visitato[v] corrisponde


(r) r e raggiunge tutti i nodi in una singolaalla passata. Nei grafi non connessi odi 1500 articoli, con pi di 500 co-autori
l
S.enqueue marcatura del nodo v
Pi

nonboolean[
fortemente connessi,
] visitato newe` necessario
boolean[1 invece fare pi`u passate, ovvero far ripartire lalgoritmo
. . . G.n]
Numero di Erds
da un nodo non
foreach u scoperto
G.V() in {r} precedenza.
do visitato[u] false
Erds ha erds = 0
Lordine
visitato[r]incuitrue vengono visitati i nodi dipende dalla politica di estrazione della procedura
remove while().not
Esistono due ()
S.isEmpty approcci
do principali: I co-autori di Erds hanno erds = 1

N ODE u S.dequeue() Se X ha scritto una pubblicazione scientifica con

Breadth-First-Search
{ esamina il nodo (uBFS } ), ovvero visita in ampiezza (detta anche a ventaglio); un co-autore con erds = k, ma non con
foreach v G.adj
Depth-First-Search (u)),do
(DFS ovvero visita in profondit`a (detta anche a scandaglio). un co-autore con erds < k, X ha erds=k +1
{ esamina larco (u, v) }
Chi non raggiunto da questa definizione ha erds = +
if not visitato[v] then
visitato[v] true
S.enqueue(v)

Alberto Montresor 31 Alberto Montresor 32


Alberto Montresor, erdos = 4 Alan Bertossi, erdos = 3
8 7

3 11 2 9

6 4 5

Figura 9.9: Un grafo non orientato

Come tributo scherzoso alla sua estrema prolificit`a, e` nato il concetto di numero di Erdos,
un coefficiente assegnato ad ogni matematico (in generale, ad ogni autore scientifico) per mi-
surare la sua distanza da Erdos. Paul Erdos ha erdos = 0. I co-autori dei suoi articoli hanno
erdos = 1. Chi ha scritto articoli in collaborazione con autori con erdos = 1 (ma non con
Erdos) ha erdos = 2. Ricorsivamente, chi ha collaborato con autori con erdos = k (ma non
con autori con erdos < k), ha erdos = k + 1. Chi non e` raggiunto da questa definizione,
ha erdos = . Il massimo numero di Erdos finito e` 15; e` scherzosamente considerato un
punto donore avere un numero di Erdos basso. Gli autori di questo libro hanno erdos 3 e 4,
rispettivamente.
Dato il grafo delle collaborazioni scientifiche (dove ogni autore e` un nodo e due autori sono33
Alberto Montresor Alberto Montresor 34

uniti da un arco se e solo se hanno scritto un articolo scientifico insieme), e` possibile calcolare
ilCalcolo
numero di delErd
numero di Erds
os di ogni autore utilizzando una visita in ampiezza a partire da Erdos. Esempio
0
erdos(G RAPH G, N ODE r, integer[ ] erdos, N ODE[ ] p) 6
Q UEUE S Queue()
S.enqueue(r) 2
3 10
foreach u G.V() {r} do erdos[u] =
erdos[r] 0 1
p[r] nil 11
while not S.isEmpty() do
N ODE u S.dequeue()
4 5
foreach v G.adj(u) do % Esamina larco (u, v) 12
9
if erdos[v] = then % Il nodo u non e` gi`a stato scoperto
erdos[v] erdos[u] + 1
p[v] u 7
S.enqueue(v)

Coda:{6}
In questa versione della BFS, invece di utilizzare un vettore di booleani per la marcatura,
utilizziamo il vettore erdos di interi, in cui i nodi non ancora scoperti hanno numero di Erdos
pari a . Il nodo radice (Erdos) viene inizializzato a zero; ogni volta che viene analizzato un35
Alberto Montresor Alberto Montresor 36
Esempio Esempio
0 0
1 6 1 6
1 1
2 2
3 9 3 2 9
1 1 2
11 11
1 1

4 5 4 5
8 10 8 10

7 7

Coda:{2,4,9} Coda:{4,9,3,1}

Alberto Montresor 37 Alberto Montresor 38

Esempio Esempio
0 0
1 6 1 6
1 1
2 2
3 2 9 3 2 9
1 2 1 2
11 11
1 1

4 5 2 10
4 5 2 10
8 8
2

7 7

Coda:{9,3,1,5} Coda:{3,1,5,8}

Alberto Montresor 39 Alberto Montresor 40


Esempio Esempio
0 0
1 6 1 6
1 1
2 2
3 2 9 3 2 9
1 2 1 2
11 11
1 1

4 5 2 10
4 5 2 10
8 8
2 2

7 7

Coda:{1,5,8} Coda:{5,8}

Alberto Montresor 41 Alberto Montresor 42

Esempio Esempio
0 0
1 6 1 6
1 1
2 2
3 2 9 3 2 9
1 2 1 2
11 11
1 1

4 2 4 5 2
5 10 10
8 8
2 2
3 3
7 7

Coda:{8,7} Coda:{7}

Alberto Montresor 43 Alberto Montresor 44


che e` un albero di copertura del grafo G radicato in r. In questo albero, i figli di u
BFS ,
u sonodeitutti i nodi vBFS
scoperti durante la visita p[r]di nil(u, v). Il cammino nellalbero che
archi
Esempio Albero cammini
il nodo r ad un nodo s e` ovviamente un cammino while not S.isEmpty
anche () ed
nel grafo, doha lunghezza erd
0 N ODE u S. dequeue ()
La procedura
La visita BFS puerdosessere memorizza
() utilizzata lalbero
per deiilcammini
ottenere camminoBFS piin un vettore
breve fra duedi padri p
1 6
p[v] contiene
vertici (numero u se v e` stato scoperto duranteforeach
di archi) la visitavdel G. adj(u)
nodo u e do
in particolare de
1
2 (u,
Albero di copertura di G radicato in r
if erdo s[v] = then
v). Il vettore p e` passato in input alla procedura erdos(), con ogni elemento del
3 2 9 inizializzato a nil. erdos[v] erdos[u] + 1
2 Memorizzato tramite vettore dei padri p
1 Una volta ottenuto il vettore p, e` possibile ottenere ilp[v] u dal nodo radice r ad u
cammino
11 Figli di u - nodi v tali che (u,v) E
rico nodo s tramite la procedura stampaCammino(). SiS.noti enqueue (v)
linteressante uso della rico
1
che epermette
v non ancora visitato
di stampare gli autori nellordine atteso da r ad s.
4 5 2 10
8 stampaCammino(N ODE r, N ODE s, N ODE[ ] p)
2 In questa versione della BFS, invece di u
3 if r = s then print s
utilizziamo il vettore erdos di interi, in cui i n
7 else if p[s] = nil then
print nessun cammino da r apari
s a . Il nodo radice (Erdos) viene inizial
else arco (u, v) e il nodo v non e` ancora stato scop
Coda:{} stampaCammino(r, p[s], p)
print s

Alberto Montresor 45 Alberto Montresor 46

Algoritmo generico per la visita Visita in profondit (depth first search, DFS)
9.5.4 Visita DFS
Alcune definizioni Alcune cose da notare: Il metodo
Visita di visita DFS e` una diretta estensione
in profondit Struttura delladivisita
dati in ordine anticipato di un
158
L'albero T contiene i vertici visitati I nodi vengono visitati al pi una ordinato.
E' spessoQuando viene visitato
una subroutine un nuovo nodo u,Ricorsione
della ci si allontana da esso
al posto il pila
di una pi`u possibil
volta (marcatura) un cammino (o catena), visitando
soluzione di altri problemi nodi (e archi) nel cammino
esplicita fino a giungere in un vico
S T contiene i vertici aperti: zato a tutti false). Come negli alberi, e` possibile d
co, ovvero in un nodo v i cui nodi adiacenti sono gi`a stati tutti visitati. Quando si e` rag
vertici i cui archi uscenti non sono Tutti i nodi raggiungibili da r Utilizzata per coprire l'intero grafo, postvisita (riga (2)).
v si torna indietro lungo lultimo arco visitato e si riprende la visita allontanandosi lu
ancora stati percorsi vengono visitati non solo i nodi raggiungibili da
altro cammino di nodi (e archi) non ancoradfs visitati.
(G RAPH Questa
G, N ODEtecnica e` unapplic
di visita] visitato)
u, boolean[
Ne segue che T contiene una singola sorgente
T-S T contiene i vertici chiusi:
della(diversamente
tecnica backtrack [cfr. 16].
da BFS) visitato[u] true
vertici i cui archi uscenti sono stati esattamente tutti i nodi Nella visita DFS, linsieme S potrebbe (1) essere
{ esamina realizzato
il nodo utramite una pila} (politic
(caso previsita)
tutti percorsi raggiungibili da r
mozione LIFO). E` pi`u naturale invece descrivere
Output foreach lalgoritmo
v G.adj(u) in do
maniera ricorsiva, in
V-T contiene i vertici non visitati pi`
u Invece
coincisodi ed
un elegante.
albero, unaLalgoritmo esamina larco (u,
foresta DF viene richiamato su un grafov)G a partire da un n
{
mentre visitato e`Gil=(V,
(depth-first) vettore if not visitato[v]
E)di booleani che rappresenta linsiemethen di nodi gi`a scoperti (in
Se u si trova lungo il cammino che dfs(G, v, visitato)
va da r al nodo v, diciamo che: Contenente un insieme di
(2) { esamina il nodo u (caso postvisita) }
u un antenato di v alberi DF
v un discendente di u
Esempio 9.14 (DFS). Lordine di visita DFS dei n
47
mendo di partire dal nodo r = 1 e che gli insiemi
48
a
Alberto Montresor Alberto Montresor
Componenti connesse e fortemente connesse Definizioni: Raggiungibilit

u Terminologia In grafo orientato (non orientato)


u Componenti connesse (connected components, CC) Se esiste un cammino (catena) c tra i vertici u e v, si dice che v raggiungibile da
u Componenti fortemente connesse (strongly connected components, SCC) u tramite c

1 raggiungibile da 4 e 4 raggiungibile da 1 ma non


u Motivazioni viceversa viceversa
u
Molti algoritmi che operano sui grafi iniziano decomponendo
il grafo nelle sue componenti
u L'algoritmo viene poi eseguito su ognuna delle componenti 2 2
u I risultati vengono poi ricomposti assieme 3 3
1 1

4 5 4 5

Alberto Montresor 49 Alberto Montresor 50

Definizioni: Grafi connessi e componenti connesse Applicazioni DFS: Componente connesse

In un grafo non orientato G Problema


G connesso esiste un cammino da ogni vertice ad ogni altro vertice Verificare se un grafo non orientato connesso
Un grafo G = (V, E) una componente connessa di G Identificare le componenti connesse di cui composto
un sottografo di G connesso e massimale
Soluzione
Definizioni Un grafo connesso se, al termine della DFS, tutti i nodi sono stati marcati
G un sottografo di G (G G) se Altrimenti, una singola passata non sufficiente e la visita deve ripartire da
e solo se V V e E E 2 un nodo non marcato, scoprendo una nuova porzione del grafo
G massimale non esiste un 3
A
1
Strutture dati
sottografo G di G che sia
connesso e pi grande di G,
Vettore id degli identificatori di componente
ovvero tale per cui G G G id[u] lidentificatore della componente connessa a cui appartiene u
4 5

6 51
Alberto Montresor Alberto Montresor 52
Componenti connesse Componenti connesse
1
integer[ ] cc(G RAPH G, S TACK S) 1 3
integer[ ] id new integer[1 . . . G.n] 2 2
2
foreach u 2 G.V() do id[u] 0 1 5 6
integer counter 0 3
1
while not S.isEmpty() do
u S.pop() 10
if id[u] = 0 then
counter counter + 1 2 3
4 2
ccdfs(G, counter , u, id) 7 11
9
return id 1
2
ccdfs(G RAPH G, integer counter , N ODE u, integer[ ] id)
id[u] counter 8
foreach v 2 G.adj(u) do
if id[v] = 0 then
ccdfs(G, counter , v, id)

Alberto Montresor 53 Alberto Montresor 54


CAPITOLO 9. GRAFI
Alberi di copertura DFS Schema DFS

La visita DFS genera lalbero (foresta) dei cammini DFS Variabili globali dfs-schema(G RAPH G, N ODE u)
Tutte le volte che viene incontrato un arco che connette un nodo marcato ad uno time orologio esamina il nodo u prima (caso pre-visita)
non marcato, esso viene inserito nellalbero T time time + 1; dt[u] time
dt discovery time
foreach v G.adj(u) do
Gli archi non inclusi in T possono essere divisi 1 2 ft finish time

esamina larco (u, v) di qualsiasi tipo
in tre categorie durante la visita: if dt[v] = 0 then
se larco esaminato passando da un nodo di T esamina larco (u, v) in T
3 4 dfs-schema(g, v)
12T ,
ad un altro nodo che suo antenato in
detto arco allindietro else if dt[u] > dt[v] and ft[v] = 0 then
1 esamina larco (u, v) allindietro
se larco esaminato passando da un nodo
else if dt[u] < dt[v] and ft[v] = 0 then
di T ad un suo discendente (che non sia figlio)
esamina larco (u, v) in avanti
in T detto arco in avanti 2 4
else
altrimenti, detto arco di attraversamento esamina larco (u, v) di attraversamento
3 esamina il nodo u dopo (caso post-visita)
time time + 1; ft[u] time
Alberto Montresor 55 Alberto Montresor 56
CAPITOLO 9. GRAFI 161
Esempio Esempio
[1, ] [1, ]
dfs-schema(G RAPH G, N ODE u)
F F
esamina il nodo u prima (caso pre-visita) [2, ]
B time time + 1; dt[u] time B
C foreach v G.adj(u) do C
I esamina larco (u, v) di qualsiasi tipo I
A if dt[v] = 0 then A
M (u, v) in T
esamina larco M
dfs-schema(g, v)
else if dt[u] > dt[v] and ft[v] = 0 then
esamina larco (u, v) allindietro
D E D E
else if dt[u] < dt[v]Land ft[v] = 0 then L
H esamina larco (u, v) in avanti H
else
esamina larco (u, v) di attraversamento
G G
esamina il nodo u dopo (caso post-visita)
time time + 1; ft[u] time

e` un antenato di u, allora esiste un cammino da v a u e un arco da u a v, ovvero un ciclo. Se


esiste un ciclo, sia v il primo nodo del ciclo che viene visitato e sia (u, v) un arco del ciclo. Il
Alberto Montresor
cammino che connette v ad u verr`a prima o poi visitato,
57 e da u verr`a scoperto larco allindietro
Alberto Montresor 58
(u, v). Adattando opportunamente lo schema di cui sopra, si ottiene lalgoritmo ciclico() che
restituisce true se il grafo contiene un ciclo. Si noti che non appena viene trovato un arco
Esempio Esempio
allindietro, la procedura termina restituendo true e chiudendo tutte le chiamate ricorsive.
[1, ] [1, ]
F boolean ciclico(G RAPH G, N ODE u) F
[2, ] [2, ]
time time + 1; dt[u] time
[3, ] B foreach v G.adj(u) do [3, ] B
C I if dt[v] = 0 then C I
A if ciclico(G, v) then return true A
else if dt[u] > dt[v] and ft[v] = 0 then
return trueM M
time time + 1; ft[u] time
D return false; D
E L [4, ] E L
H H

G 9.5.8 Applicazione schema DFS : componenti fortemente connesse G


In alcuni casi, e` possibile dimostrare la correttezza di un algoritmo in base ai tempi di ini-
zio e di fine, senza doverli effettivamente calcolare! Come esempio, si consideri il problema

Alberto Montresor 59 Alberto Montresor 60


Esempio Esempio
[1, ] [1, ]
F F
[2, ] [2, ]
[3, ] B [3, ] B
C I C I
A A [6, ]
M M
[5, ] [5, ]
[4, ] D E [4, ] D E
H L H L

G G

Alberto Montresor 61 Alberto Montresor 62

Esempio Esempio
[1, ] [1, ]
F F
[2, ] [2, ]
[3, ] B [3, ] B
C I C I
A [6, 7] A [6, 7]
M M
[5, ] [5, ]
[4, ] D E [4, ] D E
H L H L

G G
[8, ]

Alberto Montresor 63 Alberto Montresor 64


Esempio Esempio
[1, ] [1, ]
F F
[2, ] [2, ]
[3, ] B [3, ] B
C I C I
A [6, 7] A [6, 7] [10, ]
M M
[5, ] [5, ]
[4, ] D E [4, ] D E
H L H L

[9, ] [9, ]
G G
[8, ] [8, ]

Alberto Montresor 65 Alberto Montresor 66

Esempio Esempio
[1, 18] [1, 18]
F F
[2, 17] [2, 17]
[3, 16] B [3, 16] B
C I C I
A [6, 7] [10, 11] A [6, 7] [10, 11] [19, ]
M M
[5,14 ] [5,14 ]
[4,15] D E [4,15] D E
H L H L

[9, 12] [9, 12]


G G
[8, 13] [8, 13]

Alberto Montresor 67 Alberto Montresor 68


Esempio Esempio
[1, 18] [1, 18]
F F
[2, 17] [2, 17]
[3, 16] B [3, 16] B
C I CAPITOLO 9. GRAFI C I 161
A [6, 7] [10, 11] A [6, 7] [10, 11]
[19, ] [19, 22]
M M
dfs-schema(G RAPH G, N ODE u)
[5,14 ] [20, ] esamina il nodo u prima (caso pre-visita) [5,14 ] [20, 21]
D E time time +D1; dt[u] time E
[4,15] L [4,15] L
H foreach v G.adj(u) do H
esamina larco (u, v) di qualsiasi tipo
[9, 12] if dt[v] = 0 then [9, 12]
G esamina larco (u,Gv) in T
[8, 13] [8, 13]
dfs-schema(g, v)
else if dt[u] > dt[v] and ft[v] = 0 then
esamina larco (u, v) allindietro
else if dt[u] < dt[v] and ft[v] = 0 then
esamina larco (u, v) in avanti
else
esamina larco (u, v) di attraversamento
Alberto Montresor 69 Alberto Montresor 70
CAPITOLO 9. GRAFI 161esamina il nodo u dopo (caso post-visita)
time time + 1; ft[u] time
Classificazione degli archi Classificazione degli archi

dfs-schema(G RAPH G, N ODE u) u Cosa serve la classificazione?


e` un antenato di u, allora esiste un cammino da v a u e un arco da u a v, ovvero un ciclo. Se
esamina il nodo u prima (caso pre-visita) E' possibile
esiste uun ciclo, dimostrare
sia v il primo nodo delalcune propriet,
ciclo che che e sia (u, v) un arco del ciclo. Il
viene visitato
time time + 1; dt[u] time [6, 7]
cammino chepoi connette
possonov ad u verr`
essere a prima o negli
sfruttate poi visitato, e da u verr`a scoperto larco allindietro
algoritmi
foreach v G.adj(u) do D (u, v). Adattando opportunamente lo schema di cui sopra, si ottiene lalgoritmo ciclico() che
esamina larco (u, v) di qualsiasi tipo restituisce
u Esempio:true se il grafo contiene un ciclo. Si noti che non appena viene trovato un arco
allindietro, la procedura termina restituendo true e chiudendo tutte le chiamate ricorsive.
if dt[v] = 0 then [1, 8] u DAG non hanno archi all'indietro (dimostrare)
esamina larco (u, v) in T
dfs-schema(g, v) A B boolean ciclico(G RAPH G, N ODE u)
[2, 5] Variabile time:
else if dt[u] > dt[v] and ft[v] = 0 then time time + 1; dt[u] time
esamina larco (u, v) allindietro foreach v G.adj(u) do variabile globale, oppure
if dt[v] = 0 then
else if dt[u] < dt[v] and ft[v] = 0 then
E C if ciclico(G, v) then return true passata per riferimento)
esamina larco (u, v) in avanti else if dt[u] > dt[v] and ft[v] = 0 then
else [9, 10] [3, 4] return true
esamina larco (u, v) di attraversamento time time + 1; ft[u] time
return false;
esamina il nodo u dopo (caso post-visita)
time time + 1; ft[u] time
Alberto Montresor 71 Alberto Montresor 72
Ordinamento topologico Ordinamento topologico

Dato un DAG G (direct acyclic graph), un ordinamento topologico su G un Problema:


ordinamento lineare dei suoi vertici tale per cui: Fornire un algoritmo che dato un grafo orientato aciclico, ritorni un ordinamento
se G contiene larco (u,v), allora u compare prima di v nellordinamento topologico
Per transitivit, ne consegue che se v raggiungibile da u, Soluzioni
allora u compare prima di v nell'ordinamento Trovare un vertice che non abbia alcun arco
Diretta incidente in ingresso
Nota: possono esserci pi ordinamenti topologici (INEFFICIENTE!) Stampare questo vertice e rimuoverlo,
insieme ai suoi archi
Ripetere la procedura finch tutti i vertici
2 risultano rimossi
1 3 5 2 4
Basata su DFS
1 3 4 Esercizio: scrivere lo pseudocodice per
questo algoritmo
Qual la complessit?
5
1 2 3 4 5 l con matrici di adiacenza

l con liste di adiacenza

Alberto Montresor 73 Alberto Montresor 74

Soluzione diretta Ordinamento topologico basato su DFS

2 2 2 Algoritmo [2,5]
Si effettua una DFS 2
1 3 4 3 4 4 Loperazione di visita consiste
[1, 10] [6,9] [3,4]
nellaggiungere il vertice alla
5 5 5 testa di una listaat finish time 1 3 4
Si restituisce la lista di vertici
Output: Output: 1 Output: 1 3 [7,8]
Output 5
2 Sequenza ordinata di vertici,
in ordine inverso di finish time
4 4
Perch funziona?

Output: 1 3 5 Output: 1 3 5 2 Output: 1 3 5 2 4


Alberto Montresor 75 Alberto Montresor 76
12 Algoritmi e Strutture di Dati
inverso di tempo di fine.
Ordinamento topologico basato su DFS - Liste Ordinamento topologico basato su DFS - Stack

topSort(G RAPH G, S EQUENCE L) topSort(G RAPH G, S TACK S)


boolean[ ] visitato boolean[1 . . . G.n] boolean[ ] visitato boolean[1 . . . G.n]
foreach u 2 G.V() do visitato[u] false foreach u 2 G.V() do visitato[u] false
foreach u 2 G.V() do foreach u 2 G.V() do
if not visitato[u] then if not visitato[u] then
ts-dfs(G, u, visitato, L) ts-dfs(G, u, visitato, S)

ts-dfs(G RAPH G, N ODE u, boolean[ ] visitato, S EQUENCE L) ts-dfs(G RAPH G, N ODE u, boolean[ ] visitato, S TACK S)
visitato[u] true visitato[u] true
foreach v 2 G.adj(u) do foreach v 2 G.adj(u) do
if not visitato[v] then if not visitato[v] then
ts-dfs(G, v, visitato, L)
ts-dfs(G, v, visitato, S)
L.insert(L.head(), u)
S.push(u)

Alberto Montresor 77 Alberto Montresor 78

Definizioni: Grafi fortemente connessi e componenti fortemente connesse Soluzione errata


T REE lookupNode(T REE T, I TEM x)
InifunTgrafo
6= nilorientato
and T.keyG 6= x then Proviamo ad utilizzare lalgoritmo per le componenti connesse?
G return lookupNode
fortemente iif(x
connesso( < T.key,
esiste T.left,
un cammino da T.right), x)ad ogni altro
ogni vertice Risultati variano a seconda del nodo da cui si parte
else
vertice
return T
Un grafo G = (V, E) una componente fortemente connessa di G
un sottografo di G fortemente connesso e massimale

Definizioni
2
G un sottografo di G (G G) se 3
2
e solo se V V e E E 3 1
G massimale non esiste un 1 6
sottografo G di G che sia 6
fortemente connesso e pi grande 4 5
di G, ovvero tale per cui G G G.
4 5

Alberto Montresor 79 Alberto Montresor 80


Componenti fortemente connesse Componenti fortemente connesse - algoritmo

Algoritmo (Kosaraju, 1978)


integer[ ] scc(G RAPH G)
1. Effettua una DFS di G
S TACK S topSort(G) % Prima visita
2. Calcola il grafo trasposto GT CAPITOLO 9. GRAFI 163
G RAPH GT Graph() % Calcolo grafo trasposto
T
3. Effettua una DFS di G esaminando i vertici in ordine inverso di tempo di fine foreach u 2 G. V () do G T
. insertNode(u)
Questo algoritmo si basa sullosservazione
foreach u 2 G.cheV() un
do grafo G e il suo trasposto GT hanno le
4. Fornisci i vertici di ogni albero della foresta depth-first prodotta al passo
stesse 3.
componenti fortemente connesse; questo
foreach v 2 deriva
G.adj(u)dalla
do simmetria della definizione, che
come una diversa SCC GTalmeno
prevede per ogni coppia di nodi u, v, esista .insertEdge
un cammino
(v, u) da u a v e almeno un cammino
da v ad u.
Grafo trasposto return cc(GT , S) % Seconda visita
Per capire il funzionamento, e` utile considerare il grafo delle componenti Gc = (V c , E c )
Dato un grafo G = (V, E), il grafo trasposto GT = (V, ET ) formato dagli
del grafo G, stessi
definito come segue:
nodi, mentre gli archi hanno direzioni invertite: i.e,
ET ={(u,v) | (v,u) E}
V c = {C1 , C2 , . . . , Ck }, dove Ci e` li-esima componente connessa di G;
E c = {(Ci , Cj ) : (ui , uj ) E : ui Ci , uj Cj }
Costo computazione In altre parole, le componenti sono contratte in un singolo vertice, e cos` gli archi che
O(m+n) vanno da componente a componente. E` facile notare che il grafo delle componenti e` aciclico:
se cos` non fosse, i nodi delle componenti appartenenti al ciclo potrebbero tutti raggiungersi
Alberto Montresor luno con laltro; farebbero
81 quindi parte di ununica componente, una contraddizione.
Alberto Montresor 82

Estendiamo il concetto di tempo di inizio e di fine per le componenti. Sia C un sottoin-


Componenti fortemente connesse - dimostrazione correttezza sieme di V ; definiamo dt(C) come Componenti il primo fortemente connesse
tempo di scoperta - dimostrazione
e ft(C) come lultimocorrettezza
tempo di
completamento: Si pu estendere il concetto di dt e ft al grafo delle componenti
Domanda

dt(C) = min{dt[u] : u C}
Che rapporto c fra le SCC del grafo G e del suo trasposto GT ?

ft(C) = max{ft[u] : u C}
Grafo delle componenti Gc = (Vc, Ec)
Teorema
In base a queste definizioni, possiamo enunciare il seguente teorema.
Vc = {C , C , . . . , C }, dove C li-esima componente fortemente connessa di G;
1 2 k i Siano C e C due componenti distinte nel grafo orientato G = (V, E).
13
Ec ={(C ,C ): (u ,u ) E :u C ,u C }
Teorema 9.1. Siano C e C due componenti distinte nel grafo orientato G = (V, E). Suppo-
i j i j i i j j Supponiamo che esista un arco (C, C) Ec. Allora ft(C) > ft(C)
niamo che esista un arco (C, C ) E c . Allora ft(C) > ft(C ).
[9,10]
Il grafo delle [2,11] [1, 8]
componenti 2 Dimostrazione Sono dati due casi: viene scoperto prima un nodo di C
[3,10] oppure di C . 2
[11,12]
aciclico? 3 [1,12] 2 3
dt(C) < dt(C ): sia x il primo nodo scoperto in C, allistante 3 dt(C). Poiche tutti i nodi
1 1
in C C sono raggiungibili 1 da x e non ancora scoperti, la loro visita inizier`a e terminer`a
6 prima della terminazione della visita di x. Quindi ft(C) = ft(x) > ft(y), per ogni y [5,7] 6
C C {x}. Ne segue che ft(C) > ft(C ). [7,8] 6
[2, 7]
4 5 [4,9] 4 5
dt(C ) < dt(C): sia y il primo nodo scoperto 4 in C ; tutti i nodi in C sono raggiungibili
5
da y e non ancora scoperti. Al termine della visita di tutti i nodi di C , tutti i nodi[3,4] di C
non sono ancora stati
83 scoperti. La [5,6]
loro visita inizier`
a e terminer` a dopo ft(C ); ne segue che 84
Alberto Montresor Alberto Montresor
ro quindi parte di ununica componente, una contraddizione.
to diComponenti
tempo di inizio e di fine per
fortemente le componenti.
connesse Sia C un
- dimostrazione sottoin-
correttezza Componenti fortemente connesse
(C) come il primo tempo di scoperta e ft(C) come lultimo tempo di
Si pu estendere il concetto di dt e ft al grafo delle componenti Algoritmo di Tarjan (1972)

dt(C) = min{dt[u] : u C}
Tarjan, R. E. "Depth-first search and linear graph algorithms", SIAM Journal on
Computing 1(2): 146160 (1972)
ft(C) = max{ft[u] : u C}
Corollario
Algoritmo con costo O(m+n) come Kosaraju
ni, possiamo enunciare il seguente teorema.
Siano C e C due componenti distinte nel grafo orientato G = (V, E). Suppo-
E preferito a Kosaraju in quanto necessita di una sola visita e non richiede il
C due componenti distinte nel grafo orientato G = (V, E). Suppo- grafo trasposto
niamo che esista un arco (u,v) ET con u C, v C. Allora ft(C) < ft(C)
(C, C ) E . Allora ft(C) > ft(C ).
c
(u,v) ET [9,10]
(v,u)scoperto
E prima un nodo di C oppure di C . [1, 8]
ati due casi: viene [11,12] 2
c
(C, C) E
3
x il primo nodo scoperto
ft(C) < ft(C)in C, allistante dt(C). Poiche tutti i nodi
ungibili da x e non ancora scoperti, la loro visita1 inizier`a e terminer`a
ione della visita di x. Quindi ft(C) = ft(x) > ft(y), per ogni y 6 [5,7]
gue che ft(C) > ft(C ). [2, 7]
4 5
y il primo nodo scoperto in C ; tutti i nodi in C sono raggiungibili
operti. Al termine della visita di tutti i nodi di C , tutti i nodi di C
[3,4] 86
Alberto Montresor Alberto Montresor
scoperti. La loro visita inizier`a e terminer`a dopo ft(C ); ne segue che

essere letto nel modo seguente: lultimo nodo della componente C


err`a inserito nella pila prima dellultimo nodo della componente C .
otata in ordine inverso, questo significa che almeno un nodo di C
odi di C nella seconda visita. A questo punto entra in gioco il grafo
c
un arco che connette C con C , in GT esso e` sostituito da un arco
ella seconda visita quindi i nodi di C non sono raggiungibili dai nodi
viduata come una componente a se stante.