Shortest path in an unweighted graph

If every edge has weight 1, the shortest path from a source s to any vertex v is found by BFS layers: the first time we reach v, we have used the minimum number of edges. Store dist[v] = number of edges from s; initialize dist[s]=0 and relax neighbors when first discovered.

On this page
  • Idea — BFS distance = edge count
  • Algorithm
  • Example in C — same graph as BFS lesson
  • Complexity — O(V + E)

1) Relation to BFS

Use the same queue-based BFS as BFS using queue. When dequeuing u and seeing neighbor v unvisited, set dist[v] = dist[u] + 1 (and optionally record parent for path reconstruction).

2) Algorithm sketch

Single-source shortest edges (unweighted)
StepAction
1Set dist[u] = -1 for all u; dist[s]=0; enqueue s.
2While queue not empty: dequeue u.
3For each neighbor v with dist[v] < 0: set dist[v] = dist[u]+1, enqueue v.

3) Example in C

Same undirected graph as the BFS page: vertices 0–4, edges 0–1, 0–2, 1–3, 2–4. Source s = 0.

#include <stdio.h>

#define V 5
#define MAXE 16
#define INF -1

static int adj[V][MAXE];
static int deg[V];
static int dist[V];

static void add_edge(int a, int b) {
    adj[a][deg[a]++] = b;
    adj[b][deg[b]++] = a;
}

int main(void) {
    int q[V * V], front = 0, rear = 0;
    int s = 0;

    add_edge(0, 1);
    add_edge(0, 2);
    add_edge(1, 3);
    add_edge(2, 4);

    for (int i = 0; i < V; i++) dist[i] = INF;
    dist[s] = 0;
    q[rear++] = s;

    while (front < rear) {
        int u = q[front++];
        for (int i = 0; i < deg[u]; i++) {
            int v = adj[u][i];
            if (dist[v] == INF) {
                dist[v] = dist[u] + 1;
                q[rear++] = v;
            }
        }
    }

    printf("Shortest edge-count from %d:\n", s);
    for (int i = 0; i < V; i++)
        printf("  dist[%d] = %d\n", i, dist[i]);
    return 0;
}

Graph structure (same as previous)

Edges:

  • 0-1
  • 0-2
  • 1-3
  • 2-4

Visual graph:

        3
        |
        1
        |
    0 --- 2 --- 4

Initial state

Values before BFS loop starts
VariableValue
s (source)0
dist[0]0
dist[1]INF (-1)
dist[2]INF (-1)
dist[3]INF (-1)
dist[4]INF (-1)
Queue (initial)[0, _, _, _, _, ...]
front0
rear1

BFS execution step-by-step

Distance updates and queue growth
Step u (dequeued) dist[u] Neighbors v dist[v] before Condition (dist[v] == INF?) Action dist[v] after Queue (front->rear)
Start-----Initial enqueue: s=0-[0]
1001INFYesdist[1]=0+1, enqueue 11[0, 1]
2002INFYesdist[2]=0+1, enqueue 21[0, 1, 2]
31100No (already 0)skip0[1, 2]
4113INFYesdist[3]=1+1, enqueue 32[1, 2, 3]
52100Noskip0[2, 3]
6214INFYesdist[4]=1+1, enqueue 42[2, 3, 4]
73211Noskip1[3, 4]
84221Noskip1[4]
9(loop ends)----front=5, rear=5 -> exit-[]

Queue evolution

front/rear progression
StageOperationfront indexrear indexQueue Contentsfront < rear?
0Initial enqueue (s=0)01[0]Yes
1Dequeue 0, enqueue 1,20->11->3[0, 1, 2]Yes
2Dequeue 1, enqueue 31->23->4[0, 1, 2, 3]Yes
3Dequeue 2, enqueue 42->34->5[0, 1, 2, 3, 4]Yes
4Dequeue 3 (no enqueue)3->45[0, 1, 2, 3, 4]Yes
5Dequeue 4 (no enqueue)4->55[0, 1, 2, 3, 4]No (exit)

Distance array updates

How each shortest distance is discovered
VertexInitial dist[]Updated in StepFinal dist[]Meaning (shortest edges from 0)
00Step 00Source vertex (0 edges away)
1INF (-1)Step 1 (via 0)10->1 (1 edge)
2INF (-1)Step 1 (via 0)10->2 (1 edge)
3INF (-1)Step 2 (via 1)20->1->3 (2 edges)
4INF (-1)Step 3 (via 2)20->2->4 (2 edges)

BFS levels (layers from source)

Layered discovery
LevelVerticesDistance from 0
0{0}0
1{1, 2}1
2{3, 4}2

Visual level graph:

Level 2          Level 1          Level 0          Level 1          Level 2
  3   <<<<<<<<<   1   <<<<<<<<<   0   >>>>>>>>>   2   >>>>>>>>>   4
(dist=2)          (dist=1)          (dist=0)          (dist=1)          (dist=2)

Final output

Shortest edge-count from 0:
  dist[0] = 0
  dist[1] = 1
  dist[2] = 1
  dist[3] = 2
  dist[4] = 2

Key differences from previous BFS code

vis[] BFS vs dist[] BFS
AspectPrevious BFS (with vis[])This BFS (with dist[])
Tracking mechanismvis[] boolean arraydist[] integer array
Initializationmemset(vis, 0, sizeof vis)dist[i] = INF for all i
Source markingvis[start] = 1dist[s] = 0
Visited checkif (!vis[v])if (dist[v] == INF)
Additional infoNoneStores shortest path length
OutputBFS traversal orderShortest distance from source

Time Complexity: O(V + E) = O(5 + 4) = O(9)
Space Complexity: O(V) = O(5) for queue + distance array

4) Weighted graphs

If edges have different positive weights, use Dijkstra (non-negative weights) or Bellman–Ford (general edge weights). BFS distance is only for unit edges.

Key takeaway

Unweighted shortest path = BFS layering. The queue order does not change; only dist[] (and optional parent pointers) are added.

Next up: BFS using queue · Time complexity · All queue topics