Articulation Points in Graph in DSA C - Time & Space Complexity
We want to know how the time needed to find articulation points changes as the graph grows.
How does the algorithm's work increase when the graph has more nodes and edges?
Analyze the time complexity of the following code snippet.
void APUtil(int u, int visited[], int disc[], int low[], int parent[], int ap[], int V, list adj[]) {
static int time = 0;
int children = 0;
visited[u] = 1;
disc[u] = low[u] = ++time;
for (auto v : adj[u]) {
if (!visited[v]) {
children++;
parent[v] = u;
APUtil(v, visited, disc, low, parent, ap, V, adj);
low[u] = min(low[u], low[v]);
if (parent[u] == -1 && children > 1)
ap[u] = 1;
if (parent[u] != -1 && low[v] >= disc[u])
ap[u] = 1;
} else if (v != parent[u]) {
low[u] = min(low[u], disc[v]);
}
}
}
This code finds articulation points using DFS traversal and tracks discovery and low times.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Depth-first search (DFS) visits each vertex and edge once.
- How many times: Each vertex is visited once; each edge is checked once or twice.
As the graph grows, the algorithm visits every node and edge once, so work grows with nodes plus edges.
| Input Size (n = vertices, m = edges) | Approx. Operations |
|---|---|
| 10 vertices, 15 edges | About 25 operations |
| 100 vertices, 200 edges | About 300 operations |
| 1000 vertices, 5000 edges | About 6000 operations |
Pattern observation: The work grows roughly in a straight line with the total number of vertices plus edges.
Time Complexity: O(V + E)
This means the time needed grows linearly with the number of vertices and edges in the graph.
[X] Wrong: "The algorithm checks every pair of nodes, so it must be O(V²)."
[OK] Correct: The algorithm uses DFS to visit each node and edge only once, not all pairs, so it is faster than O(V²).
Understanding this linear time complexity helps you explain how graph traversal algorithms efficiently find critical points.
"What if the graph is represented by an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand articulation point definition
An articulation point is a vertex that, if removed, breaks the graph into more pieces (connected components).Step 2: Compare options with definition
Only 'A vertex that, when removed, increases the number of connected components' matches this definition exactly.Final Answer:
A vertex that, when removed, increases the number of connected components -> Option CQuick Check:
Articulation point = vertex increasing components when removed [OK]
- Confusing articulation point with highest degree vertex
- Thinking articulation point is always connected to all vertices
- Assuming isolated vertices are articulation points
Solution
Step 1: Understand adjacency list representation
An adjacency list stores neighbors for each vertex, best done with an array of vectors in C++ or array of lists in C.Step 2: Analyze options
vector<int> graph[100];: vector<int> graph[100]; is correct for adjacency list in C++ (common in DSA). int graph[100][100]; is 2D array (adjacency matrix). int* graph = malloc(sizeof(int) * 100); is incorrect memory allocation. int graph[100]; is single array, insufficient for lists.Final Answer:
vector<int> graph[100]; -> Option BQuick Check:
Adjacency list = array of vectors [OK]
- Using 2D arrays for adjacency list instead of adjacency matrix
- Incorrect memory allocation for adjacency list
- Confusing adjacency list with adjacency matrix
void dfs(int u, int parent) {
visited[u] = true;
disc[u] = low[u] = ++time;
int children = 0;
for (int v : graph[u]) {
if (!visited[v]) {
children++;
dfs(v, u);
low[u] = min(low[u], low[v]);
if (parent == -1 && children > 1)
articulation[u] = true;
if (parent != -1 && low[v] >= disc[u])
articulation[u] = true;
} else if (v != parent) {
low[u] = min(low[u], disc[v]);
}
}
}What will be the value of
articulation[1] after running dfs(0, -1) on the graph edges: 0-1, 1-2, 1-3?Solution
Step 1: Analyze graph structure and DFS
Graph edges: 0-1, 1-2, 1-3. Vertex 1 connects 0 to 2 and 3. Removing 1 disconnects graph.Step 2: Apply articulation point logic
Since 1 is not root (parent != -1) and low[v] >= disc[u] condition holds for children 2 and 3, articulation[1] is set true.Final Answer:
true -> Option AQuick Check:
Vertex 1 disconnects graph = articulation true [OK]
- Assuming root node logic applies to vertex 1
- Ignoring low and disc comparison
- Confusing parent and child roles in DFS
void dfs(int u, int parent) {
visited[u] = true;
disc[u] = low[u] = ++time;
int children = 0;
for (int v : graph[u]) {
if (!visited[v]) {
children++;
dfs(v, u);
low[u] = min(low[u], low[v]);
if (parent == -1 && children > 1)
articulation[u] = true;
if (parent != -1 && low[v] > disc[u])
articulation[u] = true;
} else if (v != parent) {
low[u] = min(low[u], disc[v]);
}
}
}Solution
Step 1: Review articulation point condition
The condition for articulation point when parent != -1 is low[v] >= disc[u], not strictly greater.Step 2: Identify impact of wrong condition
Using low[v] > disc[u] misses cases where low[v] == disc[u], causing missed articulation points.Final Answer:
The condition low[v] > disc[u] should be low[v] >= disc[u] -> Option DQuick Check:
Use >= to detect articulation points correctly [OK]
- Using > instead of >= in low and disc comparison
- Forgetting to increment children count
- Not marking visited vertices
Solution
Step 1: Analyze graph structure
Triangles: 0-1-2 and 3-4-5. Vertex 1 connects 0-1-2 triangle to 3-4-5 cluster via 1-3. Vertex 3 connects 1 to the 3-4-5 triangle.Step 2: Identify articulation points
Removing 1 disconnects {0,2} from {3,4,5}. Removing 3 disconnects {0,1,2} from {4,5} (4-5 still connected). So articulation points are 1 and 3.Final Answer:
[1,3] -> Option AQuick Check:
Vertices splitting graph = 1 and 3 [OK]
- Including vertices inside cycles as articulation points
- Missing articulation points connecting clusters
- Confusing articulation points with bridges
Ready to prove it?
Pass the test and this pattern moves unknown
