Knowledge / Computer Science and Engineering / Graph algorithms: BFS, DFS and shortest paths

Graph algorithms: BFS, DFS and shortest paths

Computer Science and Engineering (B.E./B.Tech) · Algorithms · free study notes for exams, placements and interviews

In short

Graph traversal is the systematic visiting of every reachable vertex of a graph: breadth-first search (BFS) explores level by level using a queue, depth-first search (DFS) goes as deep as possible using a stack or recursion. Shortest-path algorithms build on them - BFS for unweighted graphs, Dijkstra for non-negative weights, Bellman-Ford for negative weights, Floyd-Warshall for all pairs. Together they are the most heavily examined part of the Algorithms paper in GATE CSE and appear in almost every DSA interview round at Amazon, Microsoft, Google, Flipkart, Walmart, Swiggy, Zomato, Oracle, Samsung and the Indian service companies' advanced tests. In practice they drive Google Maps and MapmyIndia routing, Delhi Metro route planners, OSPF and RIP in networks, delivery-fleet routing, dependency resolution in build tools and recommendation graphs.

Explained

Terminology and representation

Breadth-first search (BFS)

Depth-first search (DFS)

Relaxation and the single-source shortest-path framework

Dijkstra's algorithm (non-negative weights)

Bellman-Ford, DAG relaxation and all-pairs methods

Key points

Formulas and examples

Handshaking lemma: Σ deg(v) = 2|E| (undirected); Σ in-deg(v) = Σ out-deg(v) = |E| (directed)
Max edges in a simple graph: n(n−1)/2 undirected, n(n−1) directed; a tree has exactly n−1 edges
BFS distance recurrence: dist[v] = dist[u] + 1 for the tree edge (u,v); dist[s] = 0
Relaxation: if d[u] + w(u,v) < d[v] then d[v] ← d[u] + w(u,v), π[v] ← u
Triangle inequality: δ(s,v) ≤ δ(s,u) + w(u,v), where δ is the true shortest-path cost
Bellman-Ford: after pass i, d[v] = shortest cost using ≤ i edges; V−1 passes suffice; cost O(V·E)
Floyd-Warshall: d_k[i][j] = min( d_{k−1}[i][j], d_{k−1}[i][k] + d_{k−1}[k][j] ), k = 1…n; cost Θ(V³)
Dijkstra with binary heap: O((V + E) log V); with array: O(V²); with Fibonacci heap: O(E + V log V)
A*: priority f(v) = d[v] + h(v); optimal if 0 ≤ h(v) ≤ δ(v, target) (admissible)

Symbols: V, E = vertex and edge counts; w(u,v) = edge weight (cost, distance in km, time in minutes, fare in rupees); d[v] = current estimate; δ(s,v) = true shortest cost; π[v] = predecessor; C = maximum integer weight.

Example 1 - BFS, levels and bipartiteness. Undirected graph, 8 vertices, 9 edges: 1-2, 1-3, 2-4, 2-5, 3-6, 4-7, 5-7, 6-8, 7-8. BFS from vertex 1, neighbours in increasing order.

StepDequeuedNewly enqueuedQueue after
112, 32, 3
224, 53, 4, 5
3364, 5, 6
4475, 6, 7
55-6, 7
6687, 8
77-8
88-empty

Example 2 - DFS timestamps and edge classification. Directed graph: 1→2, 1→3, 2→4, 3→4, 4→5, 5→2, 5→6. DFS from 1, neighbours in increasing order, clock starting at 1.

Vertexd[v]f[v]
1112
229
438
547
656
31011

Example 3 - Dijkstra from A. Undirected weighted graph (km): A-B 4, A-C 2, B-C 5, B-D 10, C-E 3, E-D 4, D-F 11.

Extracted (d)Updates maded[A]d[B]d[C]d[D]d[E]d[F]
init-0∞∞∞∞∞
A (0)B=4, C=2042∞∞∞
C (2)B stays 4 (2+5=7), E=5042∞5∞
B (4)D=14042145∞
E (5)D=9 (5+4 < 14)04295∞
D (9)F=200429520
F (20)-0429520

Final distances: A 0, C 2, B 4, E 5, D 9, F 20 km. Shortest path to F = A-C-E-D-F = 2+3+4+11 = 20 km (the direct-looking A-B-D-F costs 4+10+11 = 25 km). Note D's estimate was improved after it had already been given a value - that is allowed; only finalised vertices never change.

Example 4 - Bellman-Ford with a negative edge. Directed graph, source 1. Edges relaxed in the fixed order (1,2)6, (1,3)7, (2,3)8, (2,4)5, (2,5)−4, (3,4)−3, (3,5)9, (4,2)−2, (5,1)2, (5,4)7.

After passd[1]d[2]d[3]d[4]d[5]
init0∞∞∞∞
102742
20274−2
30274−2
4 (= V−1)0274−2

Example 5 - Floyd-Warshall on 4 vertices. Directed: 1→2 = 3, 1→4 = 7, 2→1 = 8, 2→3 = 2, 3→1 = 5, 3→4 = 1, 4→1 = 2.

i\j (k=0)1234
103∞7
2802∞
35∞01
42∞∞0
i\j (final)1234
10356
25023
33601
42570

Checks: 3→1 = 3 via 3→4→1 (1+2), beating the direct edge 5; 3→2 = 6 via 3→4→1→2 (1+2+3); 4→3 = 7 via 4→1→2→3 (2+3+2). Diagonal stays 0 - no negative cycle.

Reference implementations

from collections import deque
import heapq

def bfs(adj, s, n):                      # unweighted shortest paths, O(V+E)
    dist = [-1] * n; dist[s] = 0
    q = deque([s])
    while q:
        u = q.popleft()
        for v in adj[u]:
            if dist[v] == -1:            # mark on enqueue
                dist[v] = dist[u] + 1
                q.append(v)
    return dist

def dfs_iterative(adj, s, n):            # O(V+E), no recursion limit
    seen = [False] * n; st = [s]; order = []
    while st:
        u = st.pop()
        if seen[u]: continue
        seen[u] = True; order.append(u)
        for v in reversed(adj[u]): 
            if not seen[v]: st.append(v)
    return order

def dijkstra(adj, s, n):                 # adj[u] = [(v, w), ...], w >= 0
    INF = float('inf'); d = [INF] * n; d[s] = 0
    pq = [(0, s)]
    while pq:
        du, u = heapq.heappop(pq)
        if du > d[u]: continue           # stale entry
        for v, w in adj[u]:
            if du + w < d[v]:
                d[v] = du + w
                heapq.heappush(pq, (d[v], v))
    return d

def bellman_ford(edges, s, n):           # edges = [(u, v, w), ...]
    INF = float('inf'); d = [INF] * n; d[s] = 0
    for _ in range(n - 1):
        changed = False
        for u, v, w in edges:
            if d[u] != INF and d[u] + w < d[v]:
                d[v] = d[u] + w; changed = True
        if not changed: break
    for u, v, w in edges:                # Vth pass = detection
        if d[u] != INF and d[u] + w < d[v]:
            return None                  # negative-weight cycle
    return d
AlgorithmGraph typeTimeSpaceNegative weights
BFSunweightedO(V+E)O(V)n/a
0-1 BFS (deque)weights 0/1O(V+E)O(V)no
DFSanyO(V+E)O(V)n/a
Dijkstra (binary heap)weightedO((V+E) log V)O(V+E)no
Dijkstra (array)dense weightedO(V²)O(V)no
Bellman-FordweightedO(V·E)O(V)yes, detects cycles
DAG topological relaxationDAGO(V+E)O(V)yes
Floyd-Warshallall pairsΘ(V³)Θ(V²)yes, detects cycles
Johnsonall pairs, sparseO(V·E log V)O(V²)yes

Where it is used

Interview questions

Common mistakes

Related topics

Minimum spanning trees and network flow · Dynamic programming · Greedy algorithms · Time and space complexity · DSA interview patterns · Recursion and backtracking

Open in the Knowledge reader →Find jobs →