Algoritmi e Strutture Dati (Mod. B)
Algoritmi su grafi
Ricerca in profondità
(Depth-First Search) Parte IV
Algoritmo per il calcolo delle CFC
1 DFS(G)
2 Calcola il grafo trasposto GT
3 DFS(GT) ma esaminando i vertici in ordine
decrescente di tempo f[v] di fine
visita
4 fornisci i vertici di ogni albero della
foresta DF prodotta al passo 3 come una
diversa CFC
Correttezza di CFC(G)
Teorema: CFC(G) calcola correttamente le componenti fortemente connesse del grafo orientato G.
Dimostrazione: Per induzione sul numero di alberi DF trovati
durante la DFS di GT, dimostriamo che i vertici di ogni
albero DF formano una CFC.
Ipotesi induttiva: Ogni albero DF prodotto è una CFC.
Passo Base: inizialmente non ci sono alberi precedenti.
L’ipotesi induttiva vale banalmente.
Infatti: La radice r dell’ultimo albero DF è il vertice terminato per ultimo in tutto il grafo G.
r raggiunge in G tutti i vertici del suo albero DF
i vertici che r raggiunge in GT sono quelli che lo raggiungono
in G, quindi otteniamo una CFC di G.
Correttezza di CFC(G)
Teorema: CFC(G) calcola correttamente le componenti fortemente connesse del grafo orientato G.
Dimostrazione:
Passo Induttivo: Consideriamo l’albero DF T con radice r prodotto da DFS su GT e sia C(r)={vV: (v)=r}.
Dimostriamo che u è aggiunto a T se e solo se uC(r).
se: Per il Teorema 2 (sotto), ogni vertice in C(r) viene messo
nello stesso albero DF.
Poiché r C(r), e r è la radice del nuovo albero DF, ogni
elemento di C(r) verrà messo in T dalla DFS su GT
Teorema 2: In ogni DFS, tutti i vertici nella stessa
CFC compaiono nello stesso albero DF.
Correttezza di CFC(G)
Teorema: CFC(G) calcola correttamente le componenti fortemente connesse del grafo orientato G.
Dimostrazione: Dimostriamo che u è aggiunto a T se e solo se
uC(r).
solo se: Dimostriamo che ogni vertice w tale che f[(w)] < f[r] o
f[(w)] < f[r] non è posto in T.
Per induzione sul numero di alberi costruiti, ogni w tale che
f[(w)] > f[r] non è posto in T, poiché quando r è selezionato dal
ciclo in DFS, w è già stato messo nell’albero con radice (w).
Ogni w tale che f[(w)] < f[r] non può essere posto in T, se così
fosse, allora w  r e dalla formula (1) e da r = (r) segue che
f[(w)]  f[(r)]= f[r], che contraddice f[(w)] < f[r].
u  v implica che f[(v)]  f[(u)]
(1)
Correttezza di CFC(G)
Teorema: CFC(G) calcola correttamente le componenti fortemente connesse del grafo orientato G.
Dimostrazione: Dimostriamo che u è aggiunto a T se e solo se
uC(r).
solo se: Ogni w tale che f[(w)] < f[r] non può essere posto in T, se
così fosse, allora w  r e dalla formula (1) e da r = (r) segue che
f[(w)]  f[(r)]= f[r], che contraddice f[(w)] < f[r].
Quindi, T contiene solo quei vertici u per i quali f[(u)]= r.
Cioè, T è proprio uguale alla componenete fortemente connessa
C(r), e ciò completa la dimostrazoine
Esercizi su CFC
Dal libro di testo:
Esercizio 23.5-4
Esercizio 23.5-5
Altre proprietà dei grafi
Caratterizzazione di alcune importanti proprietà dei
grafi:
• Percorso di Eulero
• Circuito di Eulero
• Cicli di Hamilton
e alcune loro applicazioni!
Circuito di Eulero e Percorso di Eulero
• Un circuito di Eulero di un grafo G è un circuito in
G che visita ogni arco di G esattamente una volta.
• Una percorso di Eulero di un grafo G è un percorso
aperto in G che visita ogni arco di G esattamente
una volta.
Circuito di Eulero
• Un vertice v si dice dispari se grad(v) è dispari.
• Un vertice v si dice pari se grad(v) è pari.
Teorema: Sia G un grafo connesso. Allora G ha un
circuito di Eulero se e solo se ogni vertice di G è
pari.
Dimostrazione
 Se G ha un circuito di Eulero, allora (il grado
di) ogni vertice di G è pari.
• In un circuito di Eulero, un vertice è incontrato e
poi abbandonato da un arco differente, quindi per
ogni visita di un vertice, sono necessari due archi.
Vale anche per il vertice di partenza e arrivo.
• La somma degli archi per ogni vertice deve quindi
essere pari.
Dimostrazione
 Se (il grado di) ogni vertice di G è pari, allora
G ha un circuito di Eulero.
• Lo dimostriamo fornendo una procedura generale
per costruire un circuito di Eulero, assumendo la
condizione sopra.
Dimostrazione
 Se (il grado di) ogni vertice di G è pari, allora
G ha un circuito di Eulero.
• Lo dimostriamo fornendo una procedura generica
per costruire un circuito di Eulero che assume la
condizione sopra.
 Usiamo DFS per trovare i circuiti, eliminando via via
ogni arco attreversato.
 Appena ritorniamo al vertice di partenza, se esistono
altri archi, scegliamo uno dei vertici del ciclo trovato
per cui esiste ancora un arco. Altrimenti termina.
 Torniamo al passo 
Fusione di Circuiti
Fusione di Circuiti: esempio
Algoritmo per il circuito di Eulero
 Usiamo DFS per trovare i circuiti, eliminando
via via ogni arco attreversato.
 Appena ritorniamo al vertice di partenza, se
esistono altri archi, scegliamo uno dei vertici
del ciclo trovato per cui esiste ancora un arco.
Altrimenti va la passo 
 Torniamo al passo 
 Fondiamo, nei vertici comuni, i circuiti trovati
in un unico circuito come visto prima.
Percorso di Eulero
Teorema: Sia G un grafo connesso. G ha un percorso di Eulero se e solo se G ha esattamente 2
vertici dispari.
Inoltre, il percorso parte da uno di questi vertici
dispari e termina all’altro vertice dispari.
G ha 2 vertici dispari
G ha un percorso di Eulero
Ogni vertice di H è pari
H ha un circuito di Eulero
Cicli Hamiltoniani
• An ciclo Hamiltoniano di un grafo G è un
ciclo in G che visita ogni vertice di G
esattamente una volta.
• Applicazione: Il commesso viaggiatore.
• Trovare un ciclo Hamiltoniano in un grafo è
un “problema molto complesso”.