Graph Representation

  • A sparse graph is a graph with edges. A dense graph is a graph with edges.
  • is a graph with vertices and edges.
    • An adjacency matrix is a matrix where if and otherwise.
      • If is undirected, the adjacency matrix is symmetric.
      • The adjacency matrix representation allows us to check in time if a given edge is in the graph
      • The adjacency matrix representation requires space. (when the graph has many fewer edges than , more compact representations are possible)
      • Many graph algorithms need to examine all the edges connected to a given vertex . In the worst case, may have neighbors. However, this case is rare in practice.
    • An adjacency list is an array Adj of records, where Adj[i] contains all the vertices such that .
      • The length of Adj[v] is the degree of vertex and is denoted by .
      • In an undirected graph, each edge appears twice. the node appears in Adj[i] and the node appears in Adj[j].
      • Adjacency lists are a more compact representation of sparse graphs.
      • Adjacency lists require space
Adjacency MatrixAdjacency List
Space
Check if

Graph Traversal

  • st-connectivity is a decision problem determining if there is a path between two vertices and in a graph .

Breadth-First Search (BFS)

  • Let be a graph and be a starting node.
    • The layers of the node in the graph constructed by BFS are defined as follows:
      • (the set of vertices adjacent to )
      • (the set of vertices adjacent to the vertices in that are not in )
    • is the set of vertices at distance from .
    • BFS is not only determining the nodes reachable from , but also the shortest path from to them.
    • For each , layer produced by BFS consists of all nodes at distance exactly from .
    • There is a path from to if and only if appears in some layer.
    • BFS produces a BFS tree rooted at which is a tree .
      • (the set of nodes reachable from )
      • If and , then .
      • (3.4) If and (a non-tree edge), then either and are in the same layer, or they are in adjacent layers.
    • BFS explores the connected component in the graph containing .
      • is the set of nodes reachable from , produced as the following algorithm:
        • Start with
        • While there exists an edge such that and , add to .
      • (note: in this context, connected component refers to the set of nodes, not the subgraph induced by them)

Layered BFS Algorithm

BFS Algorithm:
Runs in O(n+m) time if the graph is represented as an adjacency list.
---
BFS(s):
	Discovered[s]=true 
	for all other v, Discovered[v]=false
	
	L[0] = {s}    // layer 0
	i = 0         // layer counter
	T = {} // BFS tree initially empty
	
	while L[i] != {} do
	    L[i+1] = {}
	    for each v in L[i] do
	      for each (v,u) in E do
	        if not Discovered[u] then
		        Discovered[u] = true
				Add u to L[i+1]
				Add (v,u) to T
		i = i+1

Queue-based BFS Algorithm

BFS Algorithm: (Queue-based)
---
BFS(s):
    Create a queue Q
    Enqueue s onto Q
    Discovered[s] = true
    
    while Q is not empty do
        v = Dequeue from Q
        for each neighbor u of v do
            if not Discovered[u] then
                Discovered[u] = true
                Parent[u] = v // Optional: 
                Enqueue u onto Q
                Add (v, u) to T  // Optional: if building a BFS tree
Print nodes of a tree T in BFS order:
---
BFS(T, s):
    Create a queue Q
    Enqueue s onto Q
    Discovered[s] = true
    
    while Q is not empty do
        dequeue v from Q and print v
        for each child u of v do
            Enqueue u onto Q

Depth-First Search (DFS)

Algorithm 2.2 DFS(G)
Input: G = (V, E) connected undirected graph on n vertices
---
for all v ∈ V do
	vistied(v) ← false
for all v ∈ V do
	if not visited(v) then
		DFS-Explore(G, v)
Algorithm 2.3 DFS-Explore(G, v)
---
visited(v) ← true
for all (v, u) ∈ E do
	if not visited(u) then
		DFS-Explore(G, u)
  • An edge is a tree edge if is visited for the first time when is explored. (i.e. visited(u) = false)
  • An edge is a back edge if is already visited when is explored. (i.e. visited(u) = true)
  • The tree that DFS constructs is called a DFS tree.

Stack-based DFS Algorithm

DFS Algorithm: (Stack-based)
Runnning time: O(n+m) (if the graph is represented as an adjacency list)
---
DFS(s):
	Initialize S to be a stack with one element s
	While S is not empty do
	    Pop v from S
	    If Explored[u] = false then 
		    Set Explored[u] = true
			For each edge (u,v) incident to u do
			    Push v onto S

Finding the Set of All Connected Components

  • Algorithm:
    1. Find the connected components that contain the node using BFS or DFS.
    2. Find a node (if any) in the graph that is not in any connected component found in step 1.
    3. Repeat step 1 with as the starting node.
  • This algorithm runs in time. (even though it may run BFS or DFS multiple times, it spends a constant amount of time on each edge and node)

3.4 Testing Bipartiteness: An Application of BFS