C++ Program to Find Number of Articulation points in a Graph



An articulation point is a vertex of the graph, which when removed, will break the graph into two or more components. 

You are given a connected undirected graph with V vertices and E edges. Your task is to find number of articulation points in the graph. To understand this better, consider the following example:

Graph:
   0
  / \ 
 1 - 2
 |
 3 - 4

Output: 2 Articulation Points
Explanation: Removing vertex 1 or 3 will split the graph into two components.

Methods to Find Articulation Points

To find articulation points in a graph, there are two methods:

DFS Traversal to Find Articulation Points

The idea behind this method is when you remove an articulation point from a graph, you need more than one DFS traversal to visit all of its neighbors. So we can keep track of the number of DFS traversals needed to visit all vertices in the graph by removing each vertex one by one.

Algorithm

  • Run a loop over all vertices in the graph
  • For each vertex, mark it as visited and start a DFS traversal
  • Count how many separate DFS calls are needed (store in count variable) to visit all neighbors.
  • If the count is greater than 1, then the vertex is an articulation point
  • Repeat this process for all vertices, and store the articulation points in a vector
  • Return the size of the vector

C++ Code to Find Articulation Points

The code below implements above algorithm in C++:

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

const int MAX = 100;

vector<int> graph[MAX];
bool visited[MAX];
int V;

// DFS function to count reachable vertices
void DFS(int u, bool visited[], int skip) {
    visited[u] = true;
    for (int v : graph[u]) {
        if (v != skip && !visited[v]) {
            DFS(v, visited, skip);
        }
    }
}

// Check if removing vertex 'u' disconnects the graph
bool isArticulationPoint(int u) {
    // Start DFS from any vertex other than 'u'
    int start = (u == 0) ? 1 : 0;
    memset(visited, false, sizeof(visited));
    
    DFS(start, visited, u);

    // If any vertex is not visited (excluding 'u'), it's an articulation point
    for (int i = 0; i < V; ++i) {
        if (i != u && !visited[i])
            return true;
    }
    return false;
}

int main() {
    int E = 5; // number of edges
    V = 5; // number of vertices
    
    // Sample graph edges
    graph[0].push_back(1);
    graph[0].push_back(2);
    graph[1].push_back(2);
    graph[1].push_back(0);
    graph[1].push_back(3);
    graph[2].push_back(0);
    graph[2].push_back(1);
    graph[3].push_back(4);
    graph[3].push_back(1);
    graph[4].push_back(3);

    cout << "Articulation points: ";
    for (int u = 0; u < V; ++u) {
        if (isArticulationPoint(u))
            cout << u << " ";
    }
    cout << endl;

    return 0;
}
Articulation points: 1 3

Time and Space Complexity

Time Complexity: The time complexity of this algorithm is O(V * (V + E)). This is because we perform separate DFS traversals for each vertex V, and each DFS traversal takes O(V + E) time.

Space Complexity: The space complexity is O(V), which is used for the visited array and the graph representation.

Tarjan's Algorithm for Articulation Points

In this method, the idea is to use a single DFS traversal, in which we maintain discovery and low values for each vertex. In DFS tree, a vertex u is an articulation point if one of the following two conditions is true.

  • u is the root of the DFS tree and has two or more children.
  • u is not the root and has a child v such that no vertex in the subtree rooted at v has a back edge to one of the ancestors of u.

C++ Code for Tarjan's Algorithm

The code below implements Tarjan's algorithm to find articulation points in a graph:

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

const int MAX = 100;
vector<int> graph[MAX];
bool visited[MAX], isArticulation[MAX];
int disc[MAX], low[MAX], parent[MAX];
int timeCounter = 0;

void DFS(int u) {
    visited[u] = true;
    disc[u] = low[u] = ++timeCounter;
    int children = 0;

    for (int v : graph[u]) {
        if (!visited[v]) {
            children++;
            parent[v] = u;
            DFS(v);

            // After visiting v, update low[u]
            low[u] = min(low[u], low[v]);

            // Rule 1: u is root and has 2 or more children
            if (parent[u] == -1 && children > 1)
                isArticulation[u] = true;

            // Rule 2: u is not root, and low[v] >= disc[u]
            if (parent[u] != -1 && low[v] >= disc[u])
                isArticulation[u] = true;
        }
        // Back edge (but not to parent)
        else if (v != parent[u]) {
            low[u] = min(low[u], disc[v]);
        }
    }
}

int main() {
    int V = 5;
    
    // Reset arrays
    memset(visited, false, sizeof(visited));
    memset(isArticulation, false, sizeof(isArticulation));
    memset(parent, -1, sizeof(parent));

    // Graph
    graph[0] = {1, 2};
    graph[1] = {0, 2, 3};
    graph[2] = {0, 1};
    graph[3] = {1, 4};
    graph[4] = {3};

    // Call DFS from each unvisited node
    for (int i = 0; i < V; ++i) {
        if (!visited[i]) {
            DFS(i);
        }
    }

    // Print articulation points
    cout << "Articulation points: ";
    for (int i = 0; i < V; ++i) {
        if (isArticulation[i]) {
            cout << i << " ";
        }
    }
    cout << endl;

    return 0;
}
Articulation points: 1 3

Time and Space Complexity of Tarjan's Algorithm

Time Complexity: The time complexity of Tarjan's algorithm is O(V + E). This is because we perform a single DFS traversal of the graph.

Space Complexity: The space complexity is O(V).

Farhan Muhamed
Farhan Muhamed

No Code Developer, Vibe Coder

Updated on: 2025-07-17T17:17:46+05:30

543 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements