Documente Academic
Documente Profesional
Documente Cultură
Orice drum x..y trece prin u Exista x....y care nu trece prin
u este punct de articulaie. u u nu mai este punct de
articulaie!
Complexitate?
O(V(V+E))
x
y
u x
y
u 4/9
u
5/8
v
2/3 v
Pentru orice muchie din subarborele lui v nu
exist nici o muchie napoi spre u sau spre un 6/7 x
nod descoperit naintea lui u.
Proiectarea Algoritmilor 2017
Puncte de articulaie. Demonstraie teorem
(Ia)
p(u) = null i u domin cel puin 2 subarbori u este punct de articulaie.
z = primul nod descoperit de DFS din care se poate ajunge la x i la y. Cf. T drumurilor albe x,y
Arb(z).
x y z u
Subarborele Subarborele
A1 A2 x y x y
Proiectarea Algoritmilor 2017
Puncte de articulaie. Demonstraie teorem
(IIa)
p(u) null i v descendent al lui u n Arb(u) a.. x
Arb(v) i (x,z) parcurs de DFS(G) are d(z) d(u)
u este punct de articulaie.
Dem (Reducere la absurd): Pp. u nu e punct
de articulaie w Arb(v), y Arb(u) a..
y..w. Fie z primul nod din y..w a.. z Arb(u) i
u
x ultimul nod din w..y a.. x Arb(u) (x,z)
Arb(u) taie frontiera Arb(u).
v
y
z Dac d(z) < d(u) contradicie (ipoteza)
Dem: Fie nodurile x i y a.. u x..y i p(u) null. Se pot forma 3 tipuri de structuri:
x y
u u u
Arb(u) Arb(u)
x
v v y A2
A1
Arb(v) Arb(v)
y x
Arb(u)
Pentru primele 2 structuri, nu trebuie sa existe muchie care sa formeze ciclu de la
nici un nod din Arb(v) ctre vreun predecesor al lui u. Altfel x..y a.. u x..y.
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3 8 8
0 Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
2 2 2
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
2 2 0
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
2 2 0
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
2 2 0
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
2 2 0
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6
// rdcina n arborele
art(u) = 1 // DFS i are mai muli subarbori
// cazul 1 al teoremei
6 6 6
Tarjan(v)
v.index = index // se seteaz nivelul nodului v
v.lowlink = index // reine strmoul nodului v
index = index + 1 // incrementez nivelul
S.push(v) // introduc v n stiv
Pentru fiecare (v, v') din E // se prelucreaz succesorii lui v
Dac (v'.index e nedefinit sau v' e n S) atunci // CTC deja identificate sunt ignorate
Dac (v'.index e nedefinit) atunci Tarjan(v') // dac nu a fost vizitat v intru n recursivitate
v.lowlink = min(v.lowlink, v'.lowlink) //actualizez strmoul
Dac (v.lowlink == v.index) atunci // printez CTC ncepnd de la coad spre rdcin
print CTC:"
Repet
v' = S.pop // extrag nodul din stiva i l printez
print v'
Pn cnd (v' == v) // pn cnd extrag rdcina
2
2 0
3
3 8 8 0
0
4 4 4 7
5 7 0
5 5
6 6 6
x v
u y x v
u y
2
2 0
3
3 8 8 0
0
4 4 4 7
5 7 0
5 5
6 6 6
x v
u y
u v
x
v
u
y
y
x
Variante:
1. Drumuri punct multipunct: pentru un nod dat s V, s se gseasc un drum de
cost minim de la s la u V; Dijkstra, Bellman-Ford
2. Drumuri multipunct punct: pentru un nod dat e V, s se gseasc un drum de
cost minim de la u V la e; GT i apoi 1
3. Drumuri punct punct: pentru dou noduri date u i v V, s se gseasc un
drum u..v de cost minim; Folosind 1
4. Drumuri multipunct multipunct: u, v V, s se gseasc un drum u..v de cost
minim. Floyd-Warshall
5. Drumuri de cost maxim!
Tem de gndire pentru acas posibil subiect de examen!
Dem: Orice drum optim are costul mai mic ca al oricrui alt
drum.
Notaii:
d[v] = costul drumului descoperit s..v;
(u,v) = costul drumului optim u..v; (u,v)= daca v R(u);
p(v) = predecesorul lui v pe drumul s..v.
d = 10 d=7
s v s v
Dijkstra_generic (G,s)
V = nodurile lui G
Ct timp (V != )
u = nod din V cu d[u] min
V = V - {u}
Dem:
v V, v R(s) d[v] = (s,v) = ; d[s] = (s,s) = 0 (iniializare)
Pt v R(s), iniializare d[v] = (s,v). Dem. prin reducere la
absurd c dup oricte relaxri, relaia se menine. Fie v primul vrf
pentru care relaxarea (u,v) determin d[v] < (s,v) dup relaxarea
(u,v): d[u] + w(u,v) = d[v] < (s,v) (s,u) + w(u,v) d[u] < (s,u).
Dar relaxarea nu modific d[u], iar v e primul pentru care d[v] <
(s,v). Contrazice presupunerea! => d[v] (s,v), v V
Cum d[v] (s,v) => odat ajuns la d[v] = (s,v), ea nu mai scade.
Cum relaxarea nu creste valorile => d[v] nu se mai modific.
Dem:
Dac nainte de relaxare d[v] > d[u] + w(u,v), prin relaxare
d[v] = d[u] + w(u,v). Altfel, d[v] d[u] + w(u,v) => dup
relaxare avem d[v] d[u] + w(u,v).
Cum d[u] = (s,u) i relaxarea (u,v) nu modific d[u] => d[v]
d[u] + w(u,v) = (s,u) + w(u,v) = (s,v) (conf. Corolar 25.2)
d[v] = (s,v)
delete V;
d[s] = 0;
Q = construiete_coada(V) // coad cu prioriti
Ct timp (Q != )
conine? E;
u = ExtrageMin(Q); // extrage din V elementul cu d[u]
minim
micoreaz_val E;
// Q = Q - {u} se execut in cadrul lui ExtrageMin
Pentru fiecare (v Q si v din succesorii lui u)
Dac (d[v] > d[u] + w(u,v))
este_vid? V.
7 8 3 24 7 8 3 6
15 6
9 24 9 15
7 8 3 6 7 8 3
24 15
9 15 9 6
7 8 3 6 7 8 3
Index 0 1 2 3 4 5 6 0 24
1 9 15 2
Valoare 7 6 15 8 24 9 3
Poziie 4 5 2 0 3 6 1 7 8 3 6
Reverse 3 6 2 4 0 1 5 3 4 5 6
conine? 1 * E = E;
este_vid? 1 * V = V.
Costuri:
insert 1 * V = V;
delete logV * V = VlogV(amortizat!);
micoreaz_val 1 * E = E;
este_vid? 1 * V = V.