Skip to content
DSA graphs 6 min read

Connected Components: Counting Islands in a Graph

A connected component is a maximal group of vertices in an undirected graph that can all reach one another. If you drop a graph on the floor and it splits into separate clusters, each cluster is one component. Counting components answers questions like “how many separate friend groups are there?” or “how many islands?” You find them by running BFS or DFS from every not-yet-visited vertex.

The core idea

Loop over all vertices. Each time you hit one that hasn’t been visited, you’ve found a new component — start a traversal from it, which marks every vertex reachable from it as visited, then increment your counter. The outer loop guarantees you catch every disconnected piece.

int countComponents(const std::vector<std::vector<int>>& adj) {
    int n = adj.size(), count = 0;
    std::vector<bool> visited(n, false);
    for (int s = 0; s < n; s++) {
        if (visited[s]) continue;
        count++;
        std::queue<int> q;            // BFS flood fill
        q.push(s); visited[s] = true;
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int v : adj[u])
                if (!visited[v]) { visited[v] = true; q.push(v); }
        }
    }
    return count;
}

Tip: You could swap the BFS flood fill for a recursive DFS — the component count is identical. Use whichever you find clearer; DFS is shorter to write, BFS avoids deep recursion.

Labeling each component

Often you want more than a count — you want to know which component each vertex belongs to. Replace the boolean visited with an integer comp array, writing the current component id as you traverse.

std::vector<int> labelComponents(const std::vector<std::vector<int>>& adj) {
    int n = adj.size(), id = 0;
    std::vector<int> comp(n, -1);
    for (int s = 0; s < n; s++) {
        if (comp[s] != -1) continue;
        std::queue<int> q; q.push(s); comp[s] = id;
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int v : adj[u])
                if (comp[v] == -1) { comp[v] = id; q.push(v); }
        }
        id++;
    }
    return comp;
}

Complexity and notes

  • Time: O(V + E) — every vertex starts at most one traversal, and each edge is seen once.
  • Space: O(V).

Connected components apply to undirected graphs. The directed analogue — strongly connected components, where every vertex must reach every other along directed edges — needs algorithms like Tarjan’s or Kosaraju’s, beyond this page. A closely related technique for components under incremental unions is union-find.

Next: detect loops with cycle detection.

Last updated June 25, 2026
Was this helpful?