You are on page 1of 32

Elementary Graph Algorithms

Graph
• A graph is a structure that consists of a set of vertices
and a set of edges between pairs of vertices
Graph

• A graph is a pair (V, E), where


– V is a set of vertices
– E is a set of pairs of vertices, called edges

• Example:
– V = {A, B, C, D, E}
– E = {(A,B), (A,D), (C,E), (D, E)}
Directed graph (digraph)

• Directed edge
– ordered pair of vertices (u,v)

• Undirected edge
– unordered pair of vertices (u,v)

• A graph with directed edges is called a


directed graph or digraph

• A graph with undirected edges is an


undirected graph or simply a graph
Weighted Graphs
• The edges in a graph may have values associated with
them known as their weights
• A graph with weighted edges is known as a weighted
graph
Terminology
• End vertices (or endpoints) of an
edge
– U and V are the endpoints of
a V
• Edges incident on a vertex a b
– a, d, and b are incident on V h j
• Adjacent vertices U d X Z
– U and V are adjacent

c e i
Degree of a vertex
– X has degree 5 W g
• Parallel edges
– h and i are parallel edges f
• Self-loop Y
– j is a self-loop
Terminology (cont.)

• A path is a sequence of vertices in


which each successive vertex is
adjacent to its predecessor V
• In a simple path, the vertices and a b
P1
edges are distinct except that the
U d X Z
first and last vertex may be the
same P2 h
c e
• Examples
– P1=(V,X,Z) is a simple path
W g
– P2=(U,W,X,Y,W,V) is a path that f
is not simple Y
Terminology (cont.)
• A cycle is a simple path in which
only the first and final vertices
are the same
• Simple cycle
– cycle such that all its
V
a b
vertices and edges are
distinct
U d X Z
• Examples C2 h
– C1=(V,X,Y,W,U,V) is a c e C1
simple cycle W g
– C2=(U,W,X,Y,W,V,U) is a
cycle that is not simple f
Y
Subgraphs
• A subgraph S of a graph G is a
graph such that
– The vertices of S are a
subset of the vertices of G
– The edges of S are a
subset of the edges of G
Subgraph
• A spanning subgraph of G is a
subgraph that contains all the
vertices of G

Spanning subgraph
Connectivity
• A graph is connected if there is
a path between every pair of
vertices
• A connected component of a
graph G is a maximal
connected subgraph of G
Connected graph

Non connected graph with two


connected components
Trees and Forests

• A (free) tree is an undirected


graph T such that
– T is connected
– T has no cycles

Tree
• A forest is an undirected
graph without cycles
• The connected components
of a forest are trees

Forest
DAG
• A directed acyclic graph (DAG) is a digraph that has no
directed cycles

D E

B
C
A DAG G
Spanning Trees and Forests

• A spanning tree of a connected


graph is a spanning subgraph that
is a tree
• A spanning tree is not unique
unless the graph is a tree
• A spanning forest of a graph is a Graph
spanning subgraph that is a forest

Spanning tree
Representation of Graphs
Two standard ways:
• Adjacency List
– preferred for sparse graphs (|E| is much less than |V|^2)
– Unless otherwise specified we will assume this
representation
• Adjacency Matrix
– Preferred for dense graphs
Adjacency List

1 2 5
1
2 1 5 4
5 2 3 4
4 2 3 5
4 3 5 4 1 2

• An array Adj of |V| lists, one per vertex


• For each vertex u in V,
– Adj[u] contains all vertices v such that there is an edge (u,v)
in E (i.e. all the vertices adjacent to u)
• Space required Θ(|V|+|E|) (Following CLRS, we will use V for |V|
and E for |E|) thus Θ(V+E)
Adjacency Matrix
1 2 3 4 5
1 0 1 0 0 1
1
2 1 0 0 1 1
5 2 3 0 0 0 1 0

4 0 1 1 0 1
4 3 1 1 0 1 0
5
Graph Traversals
• For solving most problems on graphs
– Need to systematically visit all the vertices and edges of a graph

• Two major traversals


– Breadth-First Search (BFS)
– Depth-First Search(DFS)
BFS
• Starts at some source vertex s
• Discover every vertex that is reachable from s
• Also produces a BFS tree with root s and including all
reachable vertices

• Discovers vertices in increasing order of distance from s


– Distance between v and s is the minimum number of edges on a
path from s to v

• i.e. discovers vertices in a series of layers


BFS : vertex colors stored in color[]
• Initially all undiscovered: white

• When first discovered: gray


– They represent the frontier of vertices between discovered
and undiscovered
– Frontier vertices stored in a queue
– Visits vertices across the entire breadth of this frontier

• When processed: black


Additional info stored (some applications of BFS
need this info)

• pred[u]: points to the vertex which first discovered u

• d[u]: the distance from s to u


BFS(G=(V,E),s)
for each (u in V)
color[u] = white
d[u] = infinity
pred[u] = NIL
color[s] = gray
d[s] = 0
Q.enqueue(s)
while (Q is not empty) do
u = Q.dequeue()
for each (v in Adj[u]) do
if (color(v] == white) then
color[v] = gray //discovered but not yet processed
d[v] = d[u] + 1
pred[v] = u
Q.enqueue(v) //added to the frontier
color[u] = black //processed
Analysis
• Each vertex is enqued once and dequeued once : Θ(V)

• Each adjacency list is traversed once:  deg(u )   ( E )


uV

• Total: Θ(V+E)
BFS Tree
• predecessor pointers after BFS is completed define an
inverted tree
– Reverse edges: BFS tree rooted at s
– The edges of the BFS tree are called : tree edges
– Remaining graph edges are called: cross edges
BFS and shortest paths
• Theorem: Let G=(V,E) be a directed or undirected graph,
and suppose BFS is run on G starting from vertex s.
During its execution BFS discovers every vertex v in V
that is reachable from s. Let δ(s,v) denote the number of
edges on the shortest path form s to v. Upon termination
of BFS, d[v] = δ(s,v) for all v in V.
DFS
• Start at a source vertex s
• Search as far into the graph as possible and backtrack
when there is no new vertices to discover
– recursive
color[u] and pred[u] as before
• color[u]
– Undiscovered: white
– Discovered but not finished processing: gray
– Finished: black

• pred[u]
– Pointer to the vertex that first discovered u
Time stamps,
• We store two time stamps:
– d[u]: the time vertex u is first discovered (discovery time)
– f[u]: the time we finish processing vertex u (finish time)
DFS(G) DFS-VISIT(u)
for each (u in V) do //vertex u is just discovered
color[u] = white color[u] = gray
pred[u] = NIL time = time +1
time = 0 d[u] = time
for each (u in V) do for each (v in Adj[u]) do
if (color[u] == white) //explore neighbor v
DFS-VISIT(u) if (color[v] == white) then
//v is discovered by u
pred[v] = u
DFS-VISIT(v)
DFS-VISIT invoked by color[u] = black // u is finished
each vertex exactly
f[u] = time = time+ 1
once.

Θ(V+E)
DFS Forest
• Tree edges: inverse of pred[] pointers
– Recursion tree, where the edge
(u,v) arises when processing a
vertex u, we call DFS-VISIT(v)

Remaining graph edges are classified as: s


• Back edges: (u, v) where v is an A
ancestor of u in the DFS forest (self
loops are back edges)
• Forward edges: (u, v) where v is a C
proper descendent of u in the DFS
forest B
• Cross edges: (u,v) where u and v are
not ancestors or descendents of one
another. D E
If DFS run on an undirected graph
• No difference between back and forward edges: all
called back edges
• No cross edges: can you see why?
Parenthesis Theorem
• In any DFS of a graph G= (V,E), for any two vertices u and
v, exactly one of the following three conditions holds:

– The intervals [d[u],f[u]] and [d[v],f[v]] are entirely disjoint and


neither u nor v is a descendent of the other in the DFS forest

– The interval [d[u],f[u]] is contained within interval [d[v],f[v]]


and u is a descendent of v in the DFS forest

– The interval [d[v],f[v]] is contained within interval [d[u],f[u]]


and v is a descendent of u in the DFS forest
How can we use DFS to determine whether a
graph contains any cycles?

You might also like