708502. Articulation Point - I
Articulation Point - I
Slug: articulation-point-1 Difficulty: Hard Id: 708502 Topic Tags: Graph, Data Structures Company Tags: None
Summary
The problem is about finding all the articulation points in a given graph. An articulation point is a vertex that, when removed, increases the number of connected components in the graph. The key concept involved is graph traversal and manipulation.
Detailed Explanation
To solve this problem, we can use a Depth-First Search (DFS) algorithm to traverse the graph. We will keep track of two types of vertices: root nodes and articulation points. A root node is any vertex that has no incoming edges. An articulation point is a vertex that becomes disconnected when its parent node is removed.
Here's a step-by-step breakdown of the solution:
- Initialize an empty list
articulationPointsto store all the articulation points. - Perform DFS on the graph, starting from any arbitrary vertex (let's say
v). - For each visited vertex
u, check if it is a root node or not. Ifuhas no incoming edges, mark it as a root node and recursively traverse its children. - While traversing the graph, keep track of the parent nodes for each vertex. When we visit a vertex
uwith parent nodep, increment a counterlowlink[u]to represent the lowest reachable ancestor fromu. Ifphas no incoming edges, markuas an articulation point. - After DFS traversal is complete, iterate over all vertices and check if they are articulation points or not.
Here's an ASCII art diagram of a graph with articulation points:
A
/ \
B C
/ \ / \
D---E--F
In this example, vertices B and C are root nodes. When removing vertex A, the graph becomes disconnected. Therefore, A is an articulation point.
Time complexity: O(V + E), where V is the number of vertices and E is the number of edges. Space complexity: O(V), as we need to store the parent nodes for each vertex.
Optimized Solutions
Java
public class ArticulationPoint {
public static List<Integer> findArticulationPoints(int[][] graph) {
List<Integer> articulationPoints = new ArrayList<>();
int[] lowlink = new int[graph.length];
int[] disc = new int[graph.length];
int time = 0;
for (int i = 0; i < graph.length; i++) {
if (!visited(graph, i, lowlink, disc, time, articulationPoints)) {
dfs(graph, i, -1, lowlink, disc, time, articulationPoints);
}
}
return articulationPoints;
}
private static boolean visited(int[][] graph, int u, int[] lowlink, int[] disc, int time, List<Integer> articulationPoints) {
if (disc[u] == -1) {
dfsUtil(graph, u, lowlink, disc, time, articulationPoints);
return true;
}
return false;
}
private static void dfs(int[][] graph, int v, int parent, int[] lowlink, int[] disc, int time, List<Integer> articulationPoints) {
disc[v] = time++;
lowlink[v] = time++;
for (int neighbor : graph[v]) {
if (disc[neighbor] == -1) {
dfs(graph, neighbor, v, lowlink, disc, time, articulationPoints);
lowlink[v] = Math.min(lowlink[v], lowlink[neighbor]);
if ((parent != -1 && lowlink[neighbor] >= disc[v]) || (parent == -1 && lowlink[neighbor] >= disc[v])) {
articulationPoints.add(v);
}
} else if (neighbor != parent) {
lowlink[v] = Math.min(lowlink[v], disc[neighbor]);
}
}
}
private static void dfsUtil(int[][] graph, int v, int[] lowlink, int[] disc, int time, List<Integer> articulationPoints) {
visited(graph, v, lowlink, disc, time, articulationPoints);
}
}