Bridges in Graph Tarjan's Algorithm in DSA Python - Time & Space Complexity
We want to understand how the time needed to find bridges in a graph grows as the graph gets bigger.
Specifically, how does the algorithm's work increase when we add more nodes and edges?
Analyze the time complexity of the following code snippet.
def find_bridges(graph):
n = len(graph)
time = 0
disc = [-1] * n
low = [-1] * n
bridges = []
def dfs(u, parent):
nonlocal time
disc[u] = low[u] = time
time += 1
for v in graph[u]:
if disc[v] == -1:
dfs(v, u)
low[u] = min(low[u], low[v])
if low[v] > disc[u]:
bridges.append((u, v))
elif v != parent:
low[u] = min(low[u], disc[v])
for i in range(n):
if disc[i] == -1:
dfs(i, -1)
return bridges
This code finds all bridges in an undirected graph using Tarjan's algorithm with DFS traversal.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Depth-first search (DFS) visits each node and edge once.
- How many times: Each node is visited once, and each edge is checked once during DFS.
As the number of nodes (n) and edges (m) grow, the algorithm visits each node and edge once.
| Input Size (n, m) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 25 operations (10 nodes + 15 edges) |
| 100 nodes, 200 edges | About 300 operations (100 + 200) |
| 1000 nodes, 3000 edges | About 4000 operations (1000 + 3000) |
Pattern observation: The work grows roughly in proportion to the sum of nodes and edges.
Time Complexity: O(n + m)
This means the algorithm runs in time proportional to the number of nodes plus the number of edges in the graph.
[X] Wrong: "The algorithm checks every possible pair of nodes, so it must be O(n²)."
[OK] Correct: The algorithm only visits each edge once during DFS, not every pair of nodes, so it is faster than O(n²).
Understanding this time complexity helps you explain how graph traversal algorithms efficiently handle large networks.
"What if the graph was directed instead of undirected? How would the time complexity change?"
Practice
Solution
Step 1: Understand the definition of a bridge
A bridge is an edge that, when removed, increases the number of connected components in a graph.Step 2: Purpose of Tarjan's algorithm for bridges
Tarjan's algorithm efficiently finds all such edges (bridges) in a graph using DFS and low-link values.Final Answer:
To find edges that, if removed, increase the number of connected components -> Option BQuick Check:
Bridges = edges increasing components when removed [OK]
- Confusing bridges with cycles
- Thinking it finds shortest paths
- Assuming it counts nodes
Solution
Step 1: Understand initialization purpose
Discovery and low arrays store times; initializing with -1 means unvisited nodes.Step 2: Choose correct initialization
Using [-1] * n marks all nodes as unvisited initially, which is standard practice.Final Answer:
discovery = [-1] * n; low = [-1] * n -> Option AQuick Check:
Unvisited nodes marked with -1 [OK]
- Initializing with zeros (means visited)
- Using range values (incorrect meaning)
- Setting to None (causes errors)
graph = {0: [1, 2], 1: [0, 2], 2: [0, 1, 3], 3: [2, 4], 4: [3]}Solution
Step 1: Analyze graph connections
Nodes 0,1,2 form a triangle (cycle), so no bridges there. Edges (2,3) and (3,4) connect to nodes outside the cycle.Step 2: Identify bridges
Removing edge (2,3) or (3,4) disconnects the graph, so these are bridges.Final Answer:
[(2, 3), (3, 4)] -> Option CQuick Check:
Edges breaking connectivity = bridges [OK]
- Marking cycle edges as bridges
- Missing edges connecting components
- Confusing node pairs order
def dfs(u, parent):
visited[u] = True
disc[u] = time
low[u] = time
time += 1
for v in graph[u]:
if not visited[v]:
dfs(v, u)
low[u] = min(low[u], low[v])
if low[v] > disc[u]:
bridges.append((u, v))
elif v != parent:
low[u] = min(low[u], disc[v])Solution
Step 1: Check variable usage
The variable 'time' is incremented inside dfs but not declared global or passed, causing an error.Step 2: Understand Python variable scope
Without 'global time' or passing time as argument, Python treats 'time' as local, causing UnboundLocalError.Final Answer:
time variable is not declared global or passed, causing UnboundLocalError -> Option DQuick Check:
Modify time scope to fix error [OK]
- Ignoring variable scope errors
- Changing condition operators incorrectly
- Misunderstanding parent node check
edges = [(0,1), (1,2), (2,0), (1,3), (3,4), (4,5), (5,3)]
Using Tarjan's algorithm, which edges are bridges?
Solution
Step 1: Analyze graph structure
Nodes 0,1,2 form a cycle, so edges among them are not bridges. Nodes 3,4,5 form another cycle.Step 2: Identify connecting edges
Edge (1,3) connects two cycles. Removing it disconnects the graph, so it is a bridge.Final Answer:
[(1, 3)] -> Option AQuick Check:
Bridge connects two cycles [OK]
- Marking cycle edges as bridges
- Including all edges in bridge list
- Ignoring connectivity impact
Ready to prove it?
Pass the test and this pattern moves unknown
