Bridges in Graph Tarjan's Algorithm in DSA C# - 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.
void DFS(int u, int parent) {
visited[u] = true;
disc[u] = low[u] = time++;
foreach (int v in graph[u]) {
if (v == parent) continue;
if (!visited[v]) {
DFS(v, u);
low[u] = Math.Min(low[u], low[v]);
if (low[v] > disc[u]) {
// (u, v) is a bridge
}
} else {
low[u] = Math.Min(low[u], disc[v]);
}
}
}
This code runs a depth-first search to find bridges by tracking discovery and low times for each node.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: DFS visits each node once and explores all its edges.
- How many times: Each node is visited once; each edge is checked twice (once from each end).
As the number of nodes (n) and edges (m) grow, the algorithm visits each node and edge once or twice.
| Input Size (n, m) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 40 operations (10 nodes + 30 edge checks) |
| 100 nodes, 200 edges | About 500 operations (100 nodes + 400 edge checks) |
| 1000 nodes, 3000 edges | About 7000 operations (1000 nodes + 6000 edge checks) |
Pattern observation: The work grows roughly in proportion to nodes plus edges.
Time Complexity: O(n + m)
This means the time needed grows linearly with the number of nodes and 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 explores edges that actually exist, not all pairs, so it depends on edges, not all pairs.
Understanding this linear time complexity helps you explain how efficient graph algorithms work in real problems.
It shows you can handle large graphs without slowdowns, a key skill in many coding challenges.
"What if the graph was represented as an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand what a bridge is in a graph
A bridge is an edge that, when removed, increases the number of connected components in the graph.Step 2: Identify Tarjan's algorithm goal
Tarjan's algorithm finds such edges efficiently by using depth-first search and tracking discovery and low times.Final Answer:
To find edges that, if removed, increase the number of connected components -> Option DQuick Check:
Bridges = edges increasing components when removed [OK]
- Confusing bridges with cycles
- Thinking it finds shortest paths
- Mixing bridges with articulation points
Solution
Step 1: Recall C# array declaration syntax
In C#, arrays are declared as type[] name = new type[size];Step 2: Check each option
int[] disc = new int[n]; int[] low = new int[n]; uses correct syntax for both arrays. int disc[] = new int[n]; int low[] = new int[n]; uses Java-style syntax, invalid in C#. int disc = new int[n]; int low = new int[n]; misses [] for arrays. int[] disc, low = new int[n]; declares only low as array, disc is just a variable.Final Answer:
int[] disc = new int[n]; int[] low = new int[n]; -> Option BQuick Check:
C# arrays = type[] name = new type[size] [OK]
- Using Java array syntax in C#
- Forgetting [] in declaration
- Declaring multiple arrays incorrectly
Edges: (0-1), (1-2), (2-0), (1-3) // Assume graph is adjacency list // Tarjan's algorithm finds bridges Output bridges:
Solution
Step 1: Analyze the graph structure
The edges (0-1), (1-2), and (2-0) form a cycle. The edge (1-3) connects node 3 to the cycle.Step 2: Identify bridges
Edges in a cycle are not bridges because removing them does not disconnect the graph. The edge (1-3) is a bridge because removing it disconnects node 3.Final Answer:
[(1, 3)] -> Option CQuick Check:
Only edge (1-3) disconnects graph [OK]
- Marking cycle edges as bridges
- Ignoring leaf edges as bridges
- Confusing nodes and edges
void DFS(int u, int parent) {
disc[u] = time;
low[u] = time;
time++;
foreach (int v in graph[u]) {
if (disc[v] == -1) {
DFS(v, u);
low[u] = Math.Min(low[u], low[v]);
if (low[v] > disc[u])
bridges.Add((u, v));
} else {
low[u] = Math.Min(low[u], disc[v]);
}
}
}Solution
Step 1: Examine the DFS traversal logic
The code lacks 'if (v == parent) continue;' after foreach. This check prevents processing the parent edge as a back edge, which would incorrectly lower low[u] and miss bridges.Step 2: Rule out other options
The condition 'if (low[v] > disc[u])' should be 'if (low[v] >= disc[u])': 'low[v] > disc[u]' is correct for bridges (strict >). The 'disc[u]' and 'low[u]' are not initialized before DFS: disc[u] and low[u] are set inside DFS. The 'time' variable is not incremented correctly: time++ follows assignment correctly.Final Answer:
The check 'if (v == parent) continue;' is missing -> Option AQuick Check:
Parent check avoids revisiting parent [OK]
- Forgetting to skip parent node
- Using wrong comparison operator for bridges
- Not initializing discovery times
Solution
Step 1: Analyze graph cycles and connections
Edges (0-1), (1-2), (2-0) form a cycle. Edges (3-4), (4-5), (5-3) form another cycle. Edge (1-3) connects these two cycles.Step 2: Identify bridges
Only edge (1-3) is a bridge; removing it disconnects {0,1,2} from {3,4,5}. Cycle edges like (3-4) are not bridges (path 3-5-4 remains), similarly for others.Final Answer:
[(1, 3)] -> Option AQuick Check:
Only edge (1-3) disconnects graph [OK]
- Missing bridges inside connected components
- Confusing cycle edges as bridges
- Ignoring multi-cycle connections
Ready to prove it?
Pass the test and this pattern moves unknown
