### Graph Searching Algorithms

```Graph Searching
Algorithms
S
Tree
u
v
w
x
y
z
Not
discovered
Discovered,
white nodes
Discovered,
white nodes
u
x
v
y
w
z
BFS(G, u):
1. Initialize the graph
color[u]  gray
π[u]  Nil
d[u]  0
for each other vertex
color[u]  white
x
Q
v
y
BFS(G, u):
2. Initialize the queue
QØ
Enqueue(Q, u)
w
z
u
t=u
x
Q
v
y
BFS(G, u):
3. While Q ≠ Ø
1) t  Dequeue(Q)
w
z
u
u
x
v
y
w
z
Q
t=u
r = x, v
BFS(G, u):
3. While Q ≠ Ø
2) for each r adj to t
if color[r] = white
color[r]  gray
π[r]  t
d[r]  d[t] + 1
Enqueue(Q, r)
t=u
r = x, v
x
Q
v
y
BFS(G, u):
3. While Q ≠ Ø
3) color[t]  black
w
z
u
t=v
u
x
v
y
w
z
Q
BFS(G, u):
3. While Q ≠ Ø
1) t  Dequeue(Q)
2) for each r adj to t
…
3) color[t]  black
u
x
v
y
w
z
Q
t=v
r=y
BFS(G, u):
3. While Q ≠ Ø
1) t  Dequeue(Q)
2) for each r adj to t
…
3) color[t]  black
u
x
v
y
w
z
Q
t=v
r=y
BFS(G, u):
3. While Q ≠ Ø
1) t  Dequeue(Q)
2) for each r adj to t
…
3) color[t]  black
u
x
v
y
w
z
Q
t=x
r=
BFS(G, u):
3. While Q ≠ Ø
1) t  Dequeue(Q)
2) for each r adj to t
…
3) color[t]  black
u
x
v
y
w
z
Q
t=y
r=w
BFS(G, u):
3. While Q ≠ Ø
1) t  Dequeue(Q)
2) for each r adj to t
…
3) color[t]  black
u
x
v
y
w
z
Q
t=w
r=z
BFS(G, u):
3. While Q ≠ Ø
1) t  Dequeue(Q)
2) for each r adj to t
…
3) color[t]  black
u
x
v
y
w
z
Q
t=z
r=
BFS(G, u):
3. While Q ≠ Ø
1) t  Dequeue(Q)
2) for each r adj to t
…
3) color[t]  black
u
x
v
y
w
z
BFS(G, u):
- the shortest-path distance
from u
u
x
v
y
w
z
BFS(G, u):
- the shortest-path distance
from u
- construct a tree
u
x
v
y
w
z
BFS(G, u):
- Initialization: |V|
- Enqueuing/dequeuing:
|V|
u
x
v
y
w
z
BFS(G, u):
- Initialization: O(|V|)
- Enqueuing/dequeuing:
O(|V|)
O(|E|)
=> total running time:
O(|V| + |E|)
Depth-First Search (DFS)
Depth-First Search (DFS)
d[u]: when u is discovered
f[u]: when searching adj of u
is finished
u
v
w
Depth-First Search (DFS)
timestamp: t
d[u] = t
d[u]: when u is discovered
f[u]: when searching adj of u
is finished
u
v
w
Depth-First Search (DFS)
timestamp: t+1
d[u] = t
d[u]: when u is discovered
f[u]: when searching adj of u
is finished
u
v
d[v] = t+1
w
Depth-First Search (DFS)
timestamp: t+2
d[u] = t
d[u]: when u is discovered
f[u]: when searching adj of u
is finished
u
v
d[v] = t+1
f[v] = t+2
w
Depth-First Search (DFS)
timestamp: t+3
d[u] = t
d[u]: when u is discovered
f[u]: when searching adj of u
is finished
u
v
d[v] = t+1
f[v] = t+2
w
d[w] = t+3
Depth-First Search (DFS)
timestamp: t+4
d[u] = t
d[u]: when u is discovered
f[u]: when searching adj of u
is finished
u
v
d[v] = t+1
f[v] = t+2
w
d[w] = t+3
f[v] = t+4
Depth-First Search (DFS)
timestamp: t+5
d[u] = t
f[u] = t+5
v
d[v] = t+1
f[v] = t+2
d[u]: when u is discovered
f[u]: when searching adj of u
is finished
u
w
d[w] = t+3
f[w] = t+4
Depth-First Search (DFS)
d[u] = t
f[u] = t+5
v
d[v] = t+1
f[v] = t+2
d[u]: when u is discovered
f[u]: when searching adj of u
is finished
u
w
d[w] = t+3
f[w] = t+4
1. d[u] < f[u]
2. [ d[u], f[u] ] entirely contains
[ d[v], f[v] ]
3. [ d[v], f[v] ] and [ d[w], f[w] ]
are entirely disjoint
Depth-First Search (DFS)
u
v
w
x
y
z
Not
discovered
Discovered,
white nodes
Discovered,
white nodes
Depth-First Search (DFS)
u
v
w
x
y
z
Not
discovered
Discovered,
white nodes
Discovered,
white nodes
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
for each u V[G],
color[u]  white
π[u]  Nil
time  0
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
color[u]  gray
d[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
2. for each adj v of white
π[v]  u
DFS-Visit[v]
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
2. for each adj v of white
π[v]  u
DFS-Visit[v]
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
2. for each adj v of white
π[v]  u
DFS-Visit[v]
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
3. color[u]  black
f[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
3. color[u]  black
f[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
3. color[u]  black
f[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
3. color[u]  black
f[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
3. color[u]  black
f[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
3. color[u]  black
f[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
3. color[u]  black
f[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
1. Initialization
2. For each u V[G]
if color[u] = white
DFS-Visit(u)
DFS-Visit(u):
1. Initial Setting
3. color[u]  black
f[u]  time  time + 1
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
- construct a forest
Depth-First Search (DFS)
u
x
v
y
w
z
DFS(G):
- Initialization: O(|V|)
- Traversing vertices: O(|V|)
O(|E|)
=> total running time:
O(|V| + |E|)
Topological Sorting
Topological Sorting
m
O(|V|2 + |V||E|)
Or
O(|V|2)
Brute-Force way
1. Find a vertex
without edges.
2. Put it onto the front
of the list, and
remove it from G.
3. Remove all edges
to the removed edge.
4. Repeat 1~3.
Topological Sorting
Using DFS
1. Call DFS(G)
2. When a vertex is
finished, put it onto
the front of the list.
m
O(|V| + |E|)
Topological Sorting
v enters the
list before u?
At d[u]:
Using DFS
1. Call DFS(G)
2. When a vertex is
finished, put it onto
the front of the list.
1) v is white: d[u] < d[v] < f[u]
2) v is black: f[v] < d[u]
3) v is gray: d[v] < d[u] < f[v]
Topological Sorting
v enters the
list before u?
Using DFS
1. Call DFS(G)
2. When a vertex is
finished, put it onto
the front of the list.
1) v is white: d[u] < d[v]
At d[u]:
t is gray: d[t] < d[u] < f[t]
t is black: f[t] < d[u]
Topological Sorting
u
v
w
1. If v is a descendant,
d[u] < d[v] < f[v] < f[u]
2. If v is an anscestor,
d[v] < d[u] < f[u] < f[v]
3. Otherwise,
d[v] < f[v] < d[u] < f[u]
or
d[u] < f[u] < d[v] < f[v]
Depth-First Search (DFS)
1. d[u] < f[u]
2. [ d[u], f[u] ] entirely contains
[ d[v], f[v] ]
3. [ d[v], f[v] ] and [ d[w], f[w] ]
are entirely disjoint
u
v
w
In a depth-first forest,
v is a descendant of u
if and only if
d[u] < d[v] < f[v] < f[u]
Topological Sorting
1.
If v is a descendant,
d[u] < d[v] < f[v] < f[u]
G is not acyclic.
2. If v is an anscestor,
d[v] < d[u] < f[u] < f[v]
3. Otherwise,
d[v] < f[v] < d[u] < f[u] or d[u] < f[u] < d[v] < f[v]
At d[u]:
1) v is white: d[u] < d[v]
t is gray: d[t] < d[u] < f[t]
t is black: f[t] < d[u]
Topological Sorting
1.
If v is a descendant,
d[u] < d[v] < f[v] < f[u]
v should be black.
2. If v is an anscestor,
d[v] < d[u] < f[u] < f[v]
3. Otherwise,
d[v] < f[v] < d[u] < f[u] or d[u] < f[u] < d[v] < f[v]
At d[u]:
1) v is white: d[u] < d[v]
t is gray: d[t] < d[u] < f[t]
t is black: f[t] < d[u]
Topological Sorting
1.
If v is a descendant,
d[u] < d[v] < f[v] < f[u]
2. If v is an anscestor,
d[v] < d[u] < f[u] < f[v]
3. Otherwise,
d[v] < f[v] < d[u] < f[u] or d[u] < f[u] < d[v] < f[v]
At d[u]:
1) v is white: d[u] < d[v]
t is white.
Topological Sorting
1.
If v is a descendant,
d[u] < d[v] < f[v] < f[u]
2. If v is an anscestor,
d[v] < d[u] < f[u] < f[v]
3. Otherwise,
d[v] < f[v] < d[u] < f[u] or d[u] < f[u] < d[v] < f[v]
At d[u]:
1) v is white: d[u] < d[v] < f[u]
t is white.
Topological Sorting
1.
If v is a descendant,
v will enter the
d[u] < d[v] < f[v] < f[u]
list before u.
2. If v is an anscestor,
d[v] < d[u] < f[u] < f[v]
3. Otherwise,
d[v] < f[v] < d[u] < f[u] or d[u] < f[u] < d[v] < f[v]
At d[u]:
1) v is white: d[u] < d[v] < f[u]
2) v is black: f[v] < d[u]
3) v is gray: d[v] < d[u] < f[v]
Topological Sorting
1.
If v is a descendant,
d[u] < d[v] < f[v] < f[u]
the list.
2. If v is an anscestor,
d[v] < d[u] < f[u] < f[v]
3. Otherwise,
d[v] < f[v] < d[u] < f[u] or d[u] < f[u] < d[v] < f[v]
At d[u]:
1) v is white: d[u] < d[v] < f[u]
2) v is black: f[v] < d[u]
3) v is gray: d[v] < d[u] < f[v]
Topological Sorting
1.
If v is a descendant,
d[u] < d[v] < f[v] < f[u]
G is not acyclic.
2. If v is an anscestor,
d[v] < d[u] < f[u] < f[v]
3. Otherwise,
d[v] < f[v] < d[u] < f[u] or d[u] < f[u] < d[v] < f[v]
At d[u]:
1) v is white: d[u] < d[v] < f[u]
2) v is black: f[v] < d[u]
3) v is gray: d[v] < d[u] < f[v]
Strongly Connected Component
Strongly Connected Component
Strongly Connected Component
Strongly Connected Component
3
1. Call DFS(G)
2. Arrange the vertices
in order of decreasing f(u)
4
9
5
8
1
2
6
7
Strongly Connected Component
3
1. Call DFS(G)
2. Arrange the vertices
in order of decreasing f(u)
3. Compute GT
4
9
5
8
1
2
6
7
Strongly Connected Component
3
1. Call DFS(G)
2. Arrange the vertices
in order of decreasing f(u)
3. Compute GT
4. Run DFS(GT)
4
9
5
8
1
2
6
7
Strongly Connected Component
3
1. Call DFS(G)
2. Arrange the vertices
in order of decreasing f(u)
3. Compute GT
4. Run DFS(GT)
4
9
5
8
1
2
6
7
Topological Sorting
Strongly Connected Component
Strongly Connected Component
Last f[u]
>
Last f[u]
Strongly Connected Component
3
1. Call DFS(G)
2. Arrange the vertices
in order of decreasing f(u)
4
9
5
8
1
2
6
7
Strongly Connected Component
2
1
4
3
Strongly Connected Component
2
1
4
3
Directed graph
1
1
2
3
4
5
2
3
4
5