Graph Algorithms
Graph Algorithms
Graph Algorithms
CS135
Graphs
1 1 5 5 2 2 3 3 4 a digraph 4 5 5 1 1 2 2 3 3 4 an undirected 4 graph
A graph G = (V, E): V is a finite set of vertices. E is a set of vertex pairs called edges. directed edge (arc): (u, v), u, v V undirected edge: {u, v}, u, v V, u v
2/14/02 Introduction to Algorithms CLRS16.2
Adjacency-list
1 1 5 5 4 4 2 2 3 3
1 2 3 4 5 1 4 2 3 3 4 5
Array Adj of |V| lists. Space requirement is (V + E). Query (u, v) E? takes O(E) time. Suitable for sparse graphs: |E| = o(V2).
2/14/02 Introduction to Algorithms CLRS16.3
Adjacency-matrix
1 1 5 5 4 4 2 2 3 3
A 1 2 3 4 5 1 0 1 1 0 1 2 0 0 1 1 0 3 0 0 0 0 0 4 1 0 0 0 0 5 0 0 0 1 0
A[u, v] =1 (u, v) E.
|V| |V| matrix A. Space requirement is (V2). Query (u, v) E? takes (1) time. Suitable for dense graphs: |E| = (V2).
2/14/02 Introduction to Algorithms CLRS16.4
Breadth-first search
rr vv ss tt w w u u x x
BFS(G, s) for each vertex u V[G] {s} do state[u] undiscovered state[s] discovered Q ENQUEUE(Q, s) while Q do u DEQUEUE(Q) for each v Adj[u] do if state[v] = undiscovered then state[v] discovered ENQUEUE(Q, v) state[u] completely explored
the closer the earlier can be modified to find shortest-paths from a source vertex. Denote by (s, v) the shortest-path distance from source s to vertex v V.
2/14/02 Introduction to Algorithms
CLRS16.5
rr
ss
tt
u u
2/14/02
Introduction to Algorithms
2/14/02
Introduction to Algorithms
2/14/02
Introduction to Algorithms
2/14/02
Introduction to Algorithms
2/14/02
Introduction to Algorithms
2/14/02
Introduction to Algorithms
2/14/02
Introduction to Algorithms
Introduction to Algorithms
CLRS16.14
Depth-first search
rr vv ss tt w w u u x x
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
CLRS16.15
search deeper, backtrack when stuck produces a DFS forest makes recursive calls to DFS-VISIT
2/14/02
Introduction to Algorithms
Depth-first search
r:1/ r:1/
ss
tt w w
u u x x
vv
For each node u, compute d[u]: time of first visit f[u]: time when all adjacent nodes have been visited
2/14/02
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
CLRS16.16
Introduction to Algorithms
Depth-first search
r:1/ r:1/
ss
tt w w
u u x x
v:2/ v:2/
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.17
Depth-first search
r:1/ r:1/ s:3/ s:3/
tt w w
u u x x
v:2/ v:2/
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.18
Depth-first search
r:1/ r:1/ s:3/ s:3/ t:4/ t:4/
u u x x
v:2/ v:2/
w w
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.19
Depth-first search
r:1/ r:1/ s:3/ s:3/ t:4/5 t:4/5
u u x x
v:2/ v:2/
w w
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.20
Depth-first search
r:1/ r:1/ s:3/6 s:3/6 t:4/5 t:4/5
u u x x
v:2/ v:2/
w w
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.21
Depth-first search
r:1/ r:1/ s:3/6 s:3/6 t:4/5 t:4/5
u u x x
v:2/ v:2/
w:7/ w:7/
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.22
Depth-first search
r:1/ r:1/ s:3/6 s:3/6 t:4/5 t:4/5
u u x x
v:2/ v:2/
w:7/8 w:7/8
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.23
Depth-first search
r:1/ r:1/ s:3/6 s:3/6 t:4/5 t:4/5
u u x x
v:2/9 v:2/9
w:7/8 w:7/8
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.24
Depth-first search
r:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5
u u x x
v:2/9 v:2/9
w:7/8 w:7/8
DFS(G) for each vertex u V[G] do state[u] undiscovered [u] NIL time 0 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.25
Depth-first search
r:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5
v:2/9 v:2/9
w:7/8 w:7/8
DFS(G) u:11/ for each vertex u V[G] do u:11/ state[u] undiscovered [u] NIL time 0 x x for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.26
Depth-first search
r:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5
v:2/9 v:2/9
w:7/8 w:7/8
DFS(G) u:11/ for each vertex u V[G] do u:11/ state[u] undiscovered [u] NIL time 0 x:12/ x:12/ for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.27
Depth-first search
r:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5
v:2/9 v:2/9
w:7/8 w:7/8
DFS(G) u:11/ for each vertex u V[G] do u:11/ state[u] undiscovered [u] NIL time 0 x:12/13 x:12/13 for each vertex u V[G] do if state[u] = undiscovered then DFS-VISIT(u) DFS-VISIT(u) state[u] discovered d[u] time time + 1 for each v Adj[u] do if state[v] = undiscovered then [v] u DFS-VISIT(v) state[u] completely explored f[u] time time + 1
2/14/02
Introduction to Algorithms
CLRS16.28
Depth-first search
r:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5 u:11/14 u:11/14
Running time: (V + E)
v:2/9 v:2/9 w:7/8 w:7/8 x:12/13 x:12/13
Classification of edges tree edges: those on the DFS forest back edges: those that connect descendants to ancestors (self-loops, too) forward edges: non-tree edges connecting ancestors to descendants cross edges: all other edges
2/14/02 Introduction to Algorithms
CLRS16.29
Depth-first search
r:1/10 r:1/10 s:3/6 s:3/6 t:4/5 t:4/5 u:11/14 u:11/14
v:2/9 v:2/9
w:7/8 w:7/8
x:12/13 x:12/13
r v s t w
u x
Theorem. (Parenthesis structure) Let I[u] = [d[u], f[u]]. Then either I[u] and I[v] are disjoint or one is entirely contained within the other.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 (r (v (s (t t) s) (w w) v) r) (u (x x) u)
2/14/02 Introduction to Algorithms CLRS16.30
Topological sort
u u x x vv yy w w zz
TOPOLOGICAL-SORT(G) call DFS(G) to compute the finishing times f[v] for each vertex v as each vertex is finished, insert it onto the front of a linked list return the linked list of vertices
A topological sort of a dag G = (V, E) is a linear ordering p of V such that if (u, v) E then u p v. Lemma. A directed graph is acyclic if and only if a depth-first search of G yields no back edges.
2/14/02 Introduction to Algorithms CLRS16.31
Topological sort
u:1/12 u:1/12 v:2/11 v:2/11 w:3/4 w:3/4
x:6/7 x:6/7
y:5/10 y:5/10
z:8/9 z:8/9
TOPOLOGICAL-SORT(G) call DFS(G) to compute the finishing times f[v] for each vertex v as each vertex is finished, insert it onto the front of a linked list return the linked list of vertices
u u
vv
yy
zz
x x
w w
A strongly connected component of G is a maximal set of vertices C V such that for every pair u, v V, both u v and v u, that is, u and v are reachable from each other.
2/14/02 Introduction to Algorithms CLRS16.33
g:22/23 g:22/23
h:3/20 h:3/20
i:4/19 i:4/19
j:13/14 j:13/14
k:12/15 k:12/15
l:9/10 l:9/10
STRONGLY-CONNECTED-COMPONENTS(G) call DFS(G) to compute the finishing times f[u] for each vertex u compute GT call DFS(GT), but in the main loop of DFS, consider the vertices in order of decreasing f[u] output the vertices of each tree in the DFS forest as a separate strongly connected component
2/14/02 Introduction to Algorithms CLRS16.34
g:3/4 g:3/4
h:8/9 h:8/9
i:7/10 i:7/10
j:14/19 j:14/19
k:15/18 k:15/18
l:23/24 l:23/24
The strongly connected components are therefore {a}, {g}, {b, c, h, i}, {d, e, j, k}, {f}, {l}.
2/14/02 Introduction to Algorithms CLRS16.35