Input: Graph G = (V, E), starting node s
Output: d_max, V_i for i = 0, 1, ..., d_max
dist[v] = -1 for all v in V
dist[s] = 0
d_max = 0
V_i = [] (an empty list for each layer)
queue = [s]
while queue is not empty:
u = queue.pop(0)
for each neighbor v of u:
if dist[v] == -1: # v is unvisited
dist[v] = dist[u] + 1
d_max = max(d_max, dist[v])
queue.append(v)
V_i[dist[v]].append(v)
return d_max and V_i
Since graph is connected, we have \(O(E) \geq O(V)\). Hence the time complexity is \(O(|V| + |E|) = O(|E|)\).
Core idea: To calculate \(\sigma(v)\), we can modify the standard BFS.
While traversing the graph, keep track of the number of shortest paths reaching each node \(v\).
Input: Graph G = (V, E), starting node s
Output: sigma[v] for all v in V
dist[v] = -1 for all v in V
dist[s] = 0
sigma[v] = 0 for all v in V
queue = [s]
while queue is not empty:
u = queue.pop(0)
for each neighbor v of u:
if dist[v] == -1: # v is unvisited
dist[v] = dist[u] + 1
queue.append(v)
if dist[v] == dist[u] + 1: # shortest path to v passes through u
sigma[v] += sigma[u]
return sigma[v] for all v
Input: Graph G = (V, E), source s, target t, subset U ⊆ V \ {s, t}
Output: Number of nodes in U that participate in any shortest path from s to t
dist_from_s[v] = ∞ for all v in V
Set dist_from_s[s] = 0
Perform BFS to compute dist_from_s[v] for all v in V
dist_to_t[v] = ∞ for all v in V
Set dist_to_t[t] = 0
Perform BFS to compute dist_to_t[v] for all v in V
participation_count = 0
for each u in U:
if dist_from_s[u] + dist_to_t[u] == dist_from_s[t]:
participation_count += 1
return participation_count
Core idea: Similar with (2), while traversing the graph, keep track of the number of nodes in \(U\) encountered on the shortest paths reaching each node \(v\).
Input: Graph G = (V, E), source s, target t, subset U ⊆ V \ {s, t}, integer k
Output: True if there exists a shortest path from s to t with at least k nodes in U; otherwise False
dist = {v: ∞ for v ∈ V} (Shortest distance to each node)
dist[s] = 0
queue = [(s, 0)] (BFS queue: (node, count of nodes in U on path))
count = {v: -1 for v ∈ V} (Tracks the max count of U nodes on shortest path to v)
While queue is not empty:
Pop (u, u_count) from queue
For each neighbor v of u:
If dist[v] > dist[u] + 1: (Found a shorter path to v)
dist[v] = dist[u] + 1
new_count = u_count + 1 if v ∈ U else u_count
count[v] = new_count
Push (v, new_count) into q
Else if dist[v] == dist[u] + 1: (Found another shortest path to v)
new_count = u_count + 1 if v ∈ U else u_count
If new_count > count[v]: (Update count if this path has more nodes in U)
count[v] = new_count
Push (v, new_count) into q
If count[t] ≥ k, return True; otherwise, return False.