Elementary Graph Algorithms

Elementary Graph
Algorithms
Paths and Cycles
A path is a sequence of vertices
P = (v0, v1, …, vk) such that, for
1 ≤ i ≤ k, edge (vi – 1, vi) ∈ E.
Path P is simple if no vertex
appears more than once in P.
A cycle is a sequence of vertices
C = (v0, v1, …, vk – 1) such that,
for 0 ≤ i < k, edge
(vi, v(i + 1) mod k) ∈ E.
Cycle C is simple if the path
(v0, v1, vk – 1) is simple.
a
h
d
b
g
j
e
f
c
i
Paths and Cycles
A path is a sequence of vertices P1 = (g, d, e, b, d, a, h) is not
P = (v0, v1, …, vk) such that, for simple.
1 ≤ i ≤ k, edge (vi – 1, vi) ∈ E.
a
Path P is simple if no vertex
appears more than once in P.
A cycle is a sequence of vertices
C = (v0, v1, …, vk – 1) such that,
for 0 ≤ i < k, edge
(vi, v(i + 1) mod k) ∈ E.
Cycle C is simple if the path
(v0, v1, vk – 1) is simple.
h
d
b
g
j
e
f
c
i
P2 = (f, i, c, j) is simple.
Paths and Cycles
A path is a sequence of vertices C1 = (a, h, j, c, i, f, g, d) is
P = (v0, v1, …, vk) such that, for simple.
1 ≤ i ≤ k, edge (vi – 1, vi) ∈ E.
a
Path P is simple if no vertex
appears more than once in P.
A cycle is a sequence of vertices
C = (v0, v1, …, vk – 1) such that,
for 0 ≤ i < k, edge
(vi, v(i + 1) mod k) ∈ E.
Cycle C is simple if the path
(v0, v1, vk – 1) is simple.
h
d
b
g
j
e
f
c
i
Paths and Cycles
A path is a sequence of vertices C1 = (a, h, j, c, i, f, g, d) is
P = (v0, v1, …, vk) such that, for simple.
1 ≤ i ≤ k, edge (vi – 1, vi) ∈ E.
a
Path P is simple if no vertex
appears more than once in P.
A cycle is a sequence of vertices
C = (v0, v1, …, vk – 1) such that,
for 0 ≤ i < k, edge
(vi, v(i + 1) mod k) ∈ E.
Cycle C is simple if the path
(v0, v1, vk – 1) is simple.
h
d
b
g
j
e
f
c
i
C2 = (g, d, b, h, j, c, i, e,
b) is not simple.
Subgraphs
A graph H = (W, F) is a subgraph of a graph G = (V, E) if W ⊆
V and F ⊆ E.
Subgraphs
A graph H = (W, F) is a subgraph of a graph G = (V, E) if W ⊆
V and F ⊆ E.
Spanning Graphs
A spanning graph of G is a subgraph of G that contains all
vertices of G.
Spanning Graphs
A spanning graph of G is a subgraph of G that contains all
vertices of G.
Connectivity
A graph G is connected if
there is a path between any
two vertices in G.
The connected components of
a graph are its maximal
connected subgraphs.
Trees
A tree is a graph that is connected and contains no cycles.
Spanning Trees
A spanning tree of a graph is a spanning graph that is a tree.
Adjacency List Representation of a Graph
• List of vertices
• Pointer to head of adjacency list
• List of edges
• Pointers to adjacency list entries
• Adjacency list entry
• Pointer to edge
y
u
• Pointers to endpoints
a
c
c
w
v
y
d
e
u
x
a
b
x
z
b
w
e
v
d
z
Graph Exploration
• Goal:
• Visit all the vertices in the graph of G
• Count them
• Number them
•…
• Identify the connected components of G
• Compute a spanning tree of G
Graph Exploration
ExploreGraph(G)
1
Label every vertex and edge of G as unexplored
2
for every vertex v of G
3
do if v is unexplored
4
then mark v as visited
5
S ← Adj(v)
6
while S is not empty
7
do remove an edge (u, w) from S
8
if (u, w) is unexplored
9
then if w is unexplored
10
then mark edge (u, w) as tree edge
11
mark vertex w as visited
12
S ← S ∪ Adj(w)
13
else mark edge (u, w) as a non-tree edge
Properties of ExploreGraph
Theorem: Procedure ExploreGraph visits every vertex of G.
Theorem: Every iteration of the for-loop that does not
immediately terminate completely explores a connected
component of G.
Theorem: The graph defined by the tree edges is a spanning
forest of G.
Connected Components
ConnectedComponents(G)
1
Label every vertex and edge of G as unexplored
2
c←0
3
for every vertex v of G
4
do if v is unexplored
5
then c ← c + 1
6
assign component label c to v
7
S ← Adj(v)
8
while S is not empty
9
do remove an edge (u, w) from S
10
if (u, w) is unexplored
11
then if w is unexplored
12
then mark edge (u, w) as tree edge
13
assign component label c to w
14
S ← S ∪ Adj(w)
15
else mark edge (u, w) as a non-tree edge
Breadth-First Search
BFS(G)
1
2
3
4
5
6
7
8
9
10
11
12
13
Label every vertex and edge of G as unexplored
for every vertex v of G
do if v is unexplored
Running
then mark v as visited
S ← Adj(v)
while S is not empty
do (u, w) ← Dequeue(S)
if (u, w) is unexplored
then if w is unexplored
then mark edge (u, w) as tree edge
mark vertex w as visited
Enqueue(S, Adj(w))
else mark edge (u, w) as a non-tree edge
time: O(n + m)
Properties of Breadth-First Search
Theorem: Breadth-first search visits the vertices of G by
increasing distance from the root.
L4 v ∈ L and
Theorem: For Levery
edge (v, w) in G such that
0
i
L3
w ∈ Lj, |i – j| ≤ 1.
L1
L2
Depth-First Search
DFS(G)
1
2
3
4
5
6
7
8
9
10
11
12
13
Label every vertex and edge of G as unexplored
for every vertex v of G
do if v is unexplored
Running
then mark v as visited
S ← Adj(v)
while S is not empty
do (u, w) ← Pop(S)
if (u, w) is unexplored
then if w is unexplored
then mark edge (u, w) as tree edge
mark vertex w as visited
Push(S, Adj(w))
else mark edge (u, w) as a non-tree edge
time: O(n + m)
An Important Property of Depth-First Search
Theorem: For every non-tree edge (v, w) in a depth-first
spanning tree of an undirected graph, v is an ancestor of w or
vice versa.
A Recursive Depth-First Search Algorithm
DFS(G)
1
Label every vertex and every edge of G as unexplored
2
for every vertex v of G
3
do if v is unexplored
4
then DFS(G, v)
DFS(G, v)
1
mark vertex v as visited
2
for every edge (v, w) in Adj(v)
3
do if (v, w) is unexplored
4
then if w is unexplored
5
then mark edge (v, w) as tree edge
6
DFS(G, w)
7
else mark edge (v, w) as a non-tree edge