graph algorithms I

What is a graph ?
1
5
2
3
4
What is a graph ?
G=(V,E)
V = a set of vertices
E = a set of edges
edge = unordered pair of vertices
1
5
2
3
4
What is a graph ?
G=(V,E)
V = {1,2,3,4,5}
E = {{1,5}, {3,5}, {2,3}, {2,4}, {3,4}}
1
5
2
3
4
What is a graph ?
G=(V,E)
V = {1,2,3,4,5}
E = {{1,5}, {2,3}, {2,4}, {3,4}}
1
5
2
3
4
Connectedness
1
3
5
2
4
1
5
connected
3
2
not connected
4
How can we check if a graph is connected?
Representing a graph
adjacency matrix
|V| * |V| symmetric matrix A
with Ai,j = 1 if {i,j} E
Ai,j = 0 otherwise
Representing a graph
adjacency matrix
1
5
0
0
1
0
1
0
0
1
1
0
1
1
0
1
0
0
1
1
0
0
1
0
0
0
0
3
2
4
space = (V2)
Representing a graph
adjacency matrix
0
0
1
0
1
0
0
1
1
0
1
1
0
1
0
0
1
1
0
0
1
0
0
0
0
is {u,v} an edge ?
list neighbors of v
1
3
5
2
4
space = (V2)
(?)
(?)
Representing a graph
adjacency matrix
0
0
1
0
1
0
0
1
1
0
1
1
0
1
0
0
1
1
0
0
1
0
0
0
0
is {u,v} an edge ?
list neighbors of v
1
3
5
2
4
space = (V2)
(1)
(n)
Representing a graph
adjacency lists
for each vertex v V
linked list of neighbors of v
Representing a graph
adjacency lists
1
5
1: 3,5
2: 3,4
3: 1,2,4
4: 2,3
5: 1
3
2
4
space = (E)
Representing a graph
adjacency lists
1: 3,5
2: 3,4
3: 1,2,4
4: 2,3
5: 1
1
3
5
2
4
space = (E)
is {u,v} an edge ?
list neighbors of v
(?)
(?)
Representing a graph
adjacency lists
1: 3,5
2: 3,4
3: 1,2,4
4: 2,3
5: 1
1
5
3
2
4
space = (E)
is {u,v} an edge ?
list neighbors of v
(min(dv,du))
(dv)
Representing a graph
adjacency lists
1: 3,5
2: 3,4
3: 1,2,4
4: 2,3
5: 1
space = (E)
is {u,v} in E ?
neigbors of v ?
(min{du,dv})
(dv)
adjacency matrix
0 0 1 0 1
space = (V2)
0
1
0
1
0
1
1
0
1
0
1
0
1
1
0
0
0
0
0
0
is {u,v} in E ?
neigbors of v ?
(1)
(n)
Counting connected components
How can we check if a graph is connected?
INPUT: graph G given by adjacency list
OUTPUT: number of components of G
BFS (G,v)
G – undirected graph, V={1,...,n}
seen[v] = false for all v  V
Q=queue (FIFO)
seen[v]  true
enqueue(Q,v)
while Q not empty do
w  dequeue(Q)
for each neighbor u of w
if not seen[u] then
seen[u]  true
enqueue(Q,u)
Counting connected components
C0
for all v  V do seen[v]  false
for all v  V do
if not seen[v] then
C++
BFS(G,v)
output G has C connected components
DFS
G – undirected graph, V={1,...,n}
visited[v] = false for all v  V
explore(G,v)
visited[v]  true
for each neighbor u of v
if not visited(u) then explore(G,u)
DFS
G – undirected graph, V={1,...,n}
visited[v] = false for all v  V
explore(G,v)
visited[v]  true
pre[v]  clock; clock++
for each neighbor u of v
if not visited(u) then explore(G,u)
post[v]  clock; clock++
DFS
explore(G,v)
visited[v]  true
pre[v]  clock; clock++
for each neighbor u of v
if not visited(u) then explore(G,u)
post[v]  clock; clock++
vertex  Iv := [pre[v],post[v]]
“interval property”
for u,v V either
* Iv and Iu are disjoint, or
* one is contained in the other
DFS
A
explore(G,v)
visited[v]  true
pre[v]  clock; clock++
for each neighbor u of v
if not visited(u) then explore(G,u)
post[v]  clock; clock++
B
C
D
DFS
A
explore(G,v)
visited[v]  true
pre[v]  clock; clock++
for each neighbor u of v
if not visited(u) then explore(G,u)
post[v]  clock; clock++
tree edges
B
C
D
Digraphs (directed graphs)
G=(V,E)
V = a set of vertices
E = a set of edges
edge = ordered pair of vertices
u
v
(u,v)
Digraphs (directed graphs)
adjacency lists
for each vertex v V
linked list of out-neighbors of v
adjacency matrix
|V| * |V| matrix A
with Ai,j = 1 if (i,j) E
Ai,j = 0 otherwise
Digraphs (directed graphs)
a path = sequence of vertices
v1,v2,...,vk
such that
(v1,v2) E, ... , (vk-1,vk) E
DAGs (acyclic digraphs)
a cycle = sequence of vertices
v1,v2,...,vk
such that
(v1,v2) E, ... , (vk-1,vk),(vk,v1) E
DAG = digraph with no cycle
Topological sort (linearization)
INPUT: DAG G given by adjacency list
OUTPUT: ordering of vertices such that
edges go forward
DFS on digraphs
G = digraph, V={1,...,n}
visited[v] = false for all v  V
explore(G,v)
visited[v]  true
pre[v]  clock; clock++
for each out-neighbor u of v
if not visited(u) then explore(G,u)
post[v]  clock; clock++
DFS on digraphs
A
B
C
D
DFS on digraphs
A
root
B
C
D
descendant, ancestor
child, parent
DFS on digraphs
A
tree edge
B
C
D
DFS on digraphs
A
tree edge
B
C
D
DFS on digraphs
back edge
A
tree edge
B
C
D
DFS on digraphs
back edge
A
tree edge
B
C
D
cross edge
DFS on digraphs
back edge
A
tree edge
B
forward edge
C
D
cross edge
Relationships between the intervals?
back edge
A
tree edge
B
forward edge
C
D
cross edge
Topological sort using DFS
Lemma:
digraph is a DAG
if and only if
DFS has a back edge.
Topological sort using DFS
Lemma:
digraph is a DAG
if and only if
DFS has a back edge.
Lemma:
in a DAG every edge goes
to a vertex with lower post
explore(G,v)
visited[v]  true
pre[v]  clock; clock++
for each neighbor u of v
if not visited(u) then explore(G,u)
post[v]  clock; clock++
(strong) connectedness
a digraph G is strongly connected
if for every u,v V there exists a
path from u to v in G
(strong) connectedness
How to check if a digraph is
strongly connected?
(strong) connectedness
How to check if a digraph is
strongly connected?
for every uV do
DFS(G,u)
check if every vV was visited
(strong) connectedness
How to check if a digraph is
strongly connected?
pick some uV
DFS(G,u)
check if every vV was visited
DFS(reverse(G),u)
check if every vV was visited
Strongly connected components
DAG of strongly connected components
Strongly connected components
Lemma: G and reverse(G) have
the same strongly connected
components.
Strongly connected components
DAG of strongly connected components
Strongly connected components
for all v V do color[v] white
for all v V do
if color[v]=white then
DFS(reverse(G),v)
DFS(G,u)
(vertices in order post[])