Bridges in Graph Tarjan's Algorithm in DSA Java - 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 with 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++;
for (int v : 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.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: DFS visits each node and explores all its edges once.
- How many times: Each node is visited once; each edge is checked once in the adjacency list.
The algorithm visits every node and edge once, so if the graph doubles in size, the work roughly doubles too.
| Input Size (n nodes, m edges) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 25 operations |
| 100 nodes, 150 edges | About 250 operations |
| 1000 nodes, 1500 edges | About 2500 operations |
Pattern observation: The work grows linearly with the number of nodes plus edges.
Time Complexity: O(n + m)
This means the time grows in a straight line with the total number of nodes and edges in the graph.
[X] Wrong: "The algorithm checks every possible pair of nodes, so it is O(n²)."
[OK] Correct: The algorithm only visits each node and edge once, not every pair, so it is much faster than O(n²).
Understanding this linear time complexity helps you explain how efficient graph algorithms work in real problems.
"What if the graph was represented with an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand what a bridge is in graph theory
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 is used to find such edges efficiently by using DFS and tracking discovery and low times.Final Answer:
To identify edges that, if removed, increase the number of connected components -> Option AQuick Check:
Bridges = edges increasing components [OK]
- Confusing bridges with cycles
- Thinking it finds shortest paths
- Mixing bridges with articulation points
Solution
Step 1: Check initialization of discovery and low arrays
Both arrays must be initialized with -1 to indicate unvisited nodes.Step 2: Verify correct Java syntax and usage
int[] disc = new int[n]; int[] low = new int[n]; Arrays.fill(disc, -1); Arrays.fill(low, -1); correctly creates arrays and fills them with -1 using Arrays.fill.Final Answer:
int[] disc = new int[n]; int[] low = new int[n]; Arrays.fill(disc, -1); Arrays.fill(low, -1); -> Option DQuick Check:
Arrays initialized with -1 = int[] disc = new int[n]; int[] low = new int[n]; Arrays.fill(disc, -1); Arrays.fill(low, -1); [OK]
- Not filling arrays with -1, causing wrong visited checks
- Setting arrays to null after creation
- Filling arrays with 0 instead of -1
int n = 5; List<List<Integer>> graph = new ArrayList<>(); for (int i = 0; i < n; i++) graph.add(new ArrayList<>()); graph.get(0).add(1); graph.get(1).add(0); graph.get(1).add(2); graph.get(2).add(1); graph.get(2).add(0); graph.get(0).add(2); graph.get(1).add(3); graph.get(3).add(1); graph.get(3).add(4); graph.get(4).add(3); // After running Tarjan's bridge detection, which edges are bridges?
Solution
Step 1: Analyze the graph structure
The graph has edges forming a triangle between nodes 0,1,2 and a chain 1-3-4.Step 2: Identify bridges
Edges in the triangle are not bridges because removing them doesn't disconnect the graph. Edges (1,3) and (3,4) are bridges because removing them increases components.Final Answer:
[[1, 3], [3, 4]] -> Option CQuick Check:
Bridges separate graph parts = [[1, 3], [3, 4]] [OK]
- Marking edges in cycles as bridges
- Ignoring edges that disconnect graph
- Confusing node order in edges
void dfs(int u, int parent) {
disc[u] = time;
low[u] = time;
for (int v : graph.get(u)) {
if (v == parent) continue;
if (disc[v] == -1) {
dfs(v, u);
low[u] = Math.min(low[u], low[v]);
if (low[v] > disc[u]) {
bridges.add(new int[]{u, v});
}
} else {
low[u] = Math.min(low[u], disc[v]);
}
}
}Solution
Step 1: Check time increment usage
The code assigns the current time to disc[u] and low[u] but fails to increment the time variable. This causes all nodes to receive the same discovery and low values, breaking the algorithm.Step 2: Verify other potential issues
The bridge condition (low[v] > disc[u]) is correct. The else block properly updates low[u] with disc[v] for back edges. The parent skip is correctly implemented.Final Answer:
The time variable is not incremented correctly -> Option AQuick Check:
Time increment missing [OK]
- Changing bridge condition incorrectly
- Updating low[u] with wrong values
- Misusing parent check condition
Solution
Step 1: Understand the problem with disconnected graphs
Tarjan's algorithm assumes DFS covers all nodes. For disconnected graphs, DFS from one node misses others.Step 2: Correct approach for disconnected graphs
Run DFS from every unvisited node to ensure all components are covered and bridges found.Final Answer:
Run DFS from every node that is unvisited to cover all components -> Option BQuick Check:
DFS from all unvisited nodes = Run DFS from every node that is unvisited to cover all components [OK]
- Assuming graph is always connected
- Resetting arrays incorrectly
- Changing time increments unnecessarily
Ready to prove it?
Pass the test and this pattern moves unknown
