In our previous lesson, we established the fundamental vocabulary of graph theory, learning to describe graphs through properties like degree sequences and bipartiteness. We focused on the static characteristics of a graph. Now, we will transition from describing what a graph is to exploring its structure dynamically. This lesson focuses on a cornerstone of graph algorithms: analyzing connectivity.
Our goal is to learn how to find connected components, identify critical points of failure known as cut vertices (or articulation points), and discover crucial links called cut edges (or bridges). The powerful tool that unlocks all of these is the Depth-First Search (DFS) traversal algorithm. Mastering this application of DFS is essential for solving many advanced graph problems you'll encounter in the GATE exam.
Graph Traversal and Depth-First Search (DFS)
Before we dissect graph connectivity, let's briefly revisit graph traversal. Traversing a graph means systematically visiting every vertex and edge. Given your background in Information Technology, you have likely encountered the two primary methods for this: Breadth-First Search (BFS) and Depth-First Search (DFS). For the problems in this lesson, DFS is our tool of choice.
Depth-First Search explores a graph by going as deep as possible down a path before backtracking. Imagine exploring a maze by always taking the first unexplored path you see at a junction. You follow that path to its end, then backtrack to the last junction and try the next unexplored path. This "dive-deep-then-backtrack" strategy is naturally implemented using recursion (which implicitly uses a stack).
The basic algorithm looks like this:
- Start at a vertex
u. Mark it as visited. - For each neighbor
vofu: - If
vhas not been visited, recursively call DFS onv.
We use a visited array to keep track of vertices we have already seen to avoid infinite loops in graphs with cycles.
Connected Components
In an undirected graph, a connected component is a subgraph in which any two vertices are connected to each other by a path, and which is connected to no other vertices in the supergraph. A graph that is itself connected has exactly one connected component. A graph with several disconnected parts has multiple connected components.
This graph has 10 vertices and 3 connected components. The first component is {0, 1, 2, 3}, the second is {4, 5, 6}, and the third is {7, 8, 9}.
Finding these components is a direct and elegant application of DFS.
Algorithm:
- Initialize a
visitedarray for all vertices tofalseand acountof components to 0. - Iterate through all vertices of the graph from to .
- If vertex
v_iis not visited, it means we have found a new connected component.- Increment
count. - Start a DFS traversal from
v_i. This traversal will visit every vertex in this component.
- Increment
- After the loop finishes,
countwill hold the total number of connected components.
This works because the first DFS call from an unvisited vertex will explore every single node it can reach. Any nodes left unvisited must belong to a different, separate component.
Cut Vertices (Articulation Points)
Now we move to a more subtle concept. A cut vertex, or articulation point, is a vertex in a connected graph whose removal (along with its incident edges) increases the number of connected components. These are critical nodes in a network—single points of failure. For example, a router that connects several sub-networks is an articulation point.
A naive approach would be to remove each vertex one by one and check if the graph becomes disconnected. This is very inefficient, with a time complexity of roughly . A much more efficient, algorithm exists using a single DFS traversal.
This algorithm relies on two key pieces of information maintained during the DFS traversal:
- Discovery Time
disc[u]: The time (a simple counter) when a vertexuis first visited. - Low-link Value
low[u]: The lowest discovery time reachable fromu(including itself) by traversing zero or more tree edges in the DFS tree and at most one back edge. A back edge is an edge connecting a vertex to one of its ancestors in the DFS tree. Intuitively,low[u]tells us the "highest" ancestor thatuor any of its descendants can reach through a shortcut (a back edge).
With these values, we can identify articulation points using two conditions:
- For the root of the DFS tree: The root is an articulation point if and only if it has two or more children in the DFS tree. If it only has one child, removing the root simply disconnects that one subtree, but doesn't split the graph into more components than before.
- For any non-root vertex
u: Vertexuis an articulation point if it has a childvin the DFS tree such thatlow[v] >= disc[u].- Intuition: This condition
low[v] >= disc[u]means that the earliest ancestor reachable from the subtree rooted atvisuitself, or some node belowu. There is no back edge fromvor its descendants that goes "above"u. Therefore,uis the only connection from the subtree ofvto the rest of the graph. Removinguwill disconnectvand its descendants.
- Intuition: This condition
The following video by Abdul Bari provides one of the clearest explanations of this algorithm available. It walks through the process step-by-step, showing how the disc and low values are computed and used.
5.2 Articulation Point and Biconnected Components
This video from Abdul Bari's channel is a classic resource for GATE aspirants. It meticulously explains the DFS-based algorithm for finding articulation points and biconnected components.
Watch the entire video. As you do, focus on these key stages: The definition and intuition behind articulation points. The algorithm itself. Pay very close attention to the definition of discovery time (dis), low-link value (low), and the two conditions for a vertex to be an articulation point (the root case and the non-root case). The detailed example. Trace the graph traversal along with the video. See how the low value of a parent is updated based on the low value of its child, and how back edges are used to update low values. This is the most critical part for building practical understanding.
Cut Edges (Bridges)
Closely related to cut vertices are cut edges, or bridges. A bridge is an edge in a connected graph whose removal increases the number of connected components. Like articulation points, they represent critical single points of failure, but at the level of connections rather than nodes.
An edge in a graph is a bridge if and only if it is not part of any cycle. The algorithm to find bridges is a slight modification of the one for articulation points, also using DFS with discovery times and low-link values.
Let u be a parent of v in the DFS tree. The edge is a bridge if there is no back edge from v or any of its descendants to u or any of u's ancestors.
The condition for this is:
Notice the strict inequality! Let's break this down:
- If
low[v] < disc[u], it means a descendant ofv(orvitself) has a back edge to an ancestor ofu. This creates a cycle involving the edge , so it's not a bridge. - If
low[v] == disc[u], it means a descendant ofv(orvitself) has a back edge pointing exactly tou. This also forms a cycle, so is not a bridge. - Only when
low[v] > disc[u]are we sure that all paths fromv's subtree lead back tovitself, but no higher. This means the edge is the sole connection from that component to the rest of the graph.
This video from Jenny's Lectures provides an excellent walkthrough of the bridge-finding algorithm.
6.12 Bridges(Cut Edge) in a Graph | Find All Bridges in a Graph | Graph Theory
This video by Jenny's Lectures CS IT clearly explains the concept of bridges and presents the efficient DFS-based algorithm to find them.
Watch the full video, paying attention to the following: The definition of a bridge and why a brute-force approach is inefficient. The core logic using discovery time and low-link values. Note the crucial condition low[v] > discovery[u]. The worked example. This is where the concepts solidify. Trace the calculation of discovery and low arrays and see how the condition is applied at each step to identify the bridges.
Conclusion
In this lesson, we elevated our understanding of graphs from static objects to dynamic structures we can explore. We saw how one fundamental algorithm, Depth-First Search, can be augmented to reveal deep insights about a graph's connectivity.
Key Takeaways:
- Connected Components: A simple loop that repeatedly calls DFS on unvisited vertices is all that's needed to count and identify the connected components of a graph.
- Cut Vertices (Articulation Points): These are critical nodes whose removal disconnects a graph component. They can be found in linear time using a DFS traversal and tracking
discoverytimes andlow-linkvalues. A non-root vertexuis a cut vertex if it has a childvsuch thatlow[v] >= disc[u]. - Cut Edges (Bridges): These are critical edges whose removal disconnects a graph component. They are identified with a similar DFS-based algorithm. An edge (where
vis a child ofu) is a bridge iflow[v] > disc[u].
We have now analyzed the structural integrity of graphs. In our next lesson, we will shift our focus to another classic problem: finding specific kinds of paths within a graph. We will investigate the conditions under which a graph contains an Eulerian path (a path that traverses every edge exactly once) or a Hamiltonian path (a path that visits every vertex exactly once). These problems have famous historical origins and introduce new ways of thinking about graph traversal.