Open In App

Biconnected Components

Last Updated : 13 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

A biconnected component is a maximal biconnected subgraph.

Biconnected Graph is already discussed here. In this article, we will see how to find biconnected component in a graph using algorithm by John Hopcroft and Robert Tarjan.

Biconnected Components

In above graph, following are the biconnected components: 

  • 4–2 3–4 3–1 2–3 1–2
  • 8–9
  • 8–5 7–8 5–7
  • 6–0 5–6 1–5 0–1
  • 10–11

Algorithm is based on Disc and Low Values discussed in Strongly Connected Components Article.

Idea is to store visited edges in a stack while DFS on a graph and keep looking for Articulation Points (highlighted in above figure). As soon as an Articulation Point u is found, all edges visited while DFS from node u onwards will form one biconnected component. When DFS completes for one connected component, all edges present in stack will form a biconnected component. 

If there is no Articulation Point in graph, then graph is biconnected and so there will be one biconnected component which is the graph itself.

C++




// A C++ program to find biconnected components in a given undirected graph
#include <iostream>
#include <list>
#include <stack>
#define NIL -1
using namespace std;
int count = 0;
class Edge {
public:
    int u;
    int v;
    Edge(int u, int v);
};
Edge::Edge(int u, int v)
{
    this->u = u;
    this->v = v;
}
 
// A class that represents an directed graph
class Graph {
    int V; // No. of vertices
    int E; // No. of edges
    list<int>* adj; // A dynamic array of adjacency lists
 
    // A Recursive DFS based function used by BCC()
    void BCCUtil(int u, int disc[], int low[],
                 list<Edge>* st, int parent[]);
 
public:
    Graph(int V); // Constructor
    void addEdge(int v, int w); // function to add an edge to graph
    void BCC(); // prints strongly connected components
};
 
Graph::Graph(int V)
{
    this->V = V;
    this->E = 0;
    adj = new list<int>[V];
}
 
void Graph::addEdge(int v, int w)
{
    adj[v].push_back(w);
    E++;
}
 
// A recursive function that finds and prints strongly connected
// components using DFS traversal
// u --> The vertex to be visited next
// disc[] --> Stores discovery times of visited vertices
// low[] -- >> earliest visited vertex (the vertex with minimum
// discovery time) that can be reached from subtree
// rooted with current vertex
// *st -- >> To store visited edges
void Graph::BCCUtil(int u, int disc[], int low[], list<Edge>* st,
                    int parent[])
{
    // A static variable is used for simplicity, we can avoid use
    // of static variable by passing a pointer.
    static int time = 0;
 
    // Initialize discovery time and low value
    disc[u] = low[u] = ++time;
    int children = 0;
 
    // Go through all vertices adjacent to this
    list<int>::iterator i;
    for (i = adj[u].begin(); i != adj[u].end(); ++i) {
        int v = *i; // v is current adjacent of 'u'
 
        // If v is not visited yet, then recur for it
        if (disc[v] == -1) {
            children++;
            parent[v] = u;
            // store the edge in stack
            st->push_back(Edge(u, v));
            BCCUtil(v, disc, low, st, parent);
 
            // Check if the subtree rooted with 'v' has a
            // connection to one of the ancestors of 'u'
            // Case 1 -- per Strongly Connected Components Article
            low[u] = min(low[u], low[v]);
 
            // If u is an articulation point,
            // pop all edges from stack till u -- v
            if ((disc[u] == 1 && children > 1) || (disc[u] > 1 && low[v] >= disc[u])) {
                while (st->back().u != u || st->back().v != v) {
                    cout << st->back().u << "--" << st->back().v << " ";
                    st->pop_back();
                }
                cout << st->back().u << "--" << st->back().v;
                st->pop_back();
                cout << endl;
                count++;
            }
        }
 
        // Update low value of 'u' only of 'v' is still in stack
        // (i.e. it's a back edge, not cross edge).
        // Case 2 -- per Strongly Connected Components Article
        else if (v != parent[u]) {
            low[u] = min(low[u], disc[v]);
            if (disc[v] < disc[u]) {
                st->push_back(Edge(u, v));
            }
        }
    }
}
 
// The function to do DFS traversal. It uses BCCUtil()
void Graph::BCC()
{
    int* disc = new int[V];
    int* low = new int[V];
    int* parent = new int[V];
    list<Edge>* st = new list<Edge>[E];
 
    // Initialize disc and low, and parent arrays
    for (int i = 0; i < V; i++) {
        disc[i] = NIL;
        low[i] = NIL;
        parent[i] = NIL;
    }
 
    for (int i = 0; i < V; i++) {
        if (disc[i] == NIL)
            BCCUtil(i, disc, low, st, parent);
 
        int j = 0;
        // If stack is not empty, pop all edges from stack
        while (st->size() > 0) {
            j = 1;
            cout << st->back().u << "--" << st->back().v << " ";
            st->pop_back();
        }
        if (j == 1) {
            cout << endl;
            count++;
        }
    }
}
 
// Driver program to test above function
int main()
{
    Graph g(12);
    g.addEdge(0, 1);
    g.addEdge(1, 0);
    g.addEdge(1, 2);
    g.addEdge(2, 1);
    g.addEdge(1, 3);
    g.addEdge(3, 1);
    g.addEdge(2, 3);
    g.addEdge(3, 2);
    g.addEdge(2, 4);
    g.addEdge(4, 2);
    g.addEdge(3, 4);
    g.addEdge(4, 3);
    g.addEdge(1, 5);
    g.addEdge(5, 1);
    g.addEdge(0, 6);
    g.addEdge(6, 0);
    g.addEdge(5, 6);
    g.addEdge(6, 5);
    g.addEdge(5, 7);
    g.addEdge(7, 5);
    g.addEdge(5, 8);
    g.addEdge(8, 5);
    g.addEdge(7, 8);
    g.addEdge(8, 7);
    g.addEdge(8, 9);
    g.addEdge(9, 8);
    g.addEdge(10, 11);
    g.addEdge(11, 10);
    g.BCC();
    cout << "Above are " << count << " biconnected components in graph";
    return 0;
}


Java




// A Java program to find biconnected components in a given
// undirected graph
import java.io.*;
import java.util.*;
 
// This class represents a directed graph using adjacency
// list representation
class Graph {
    private int V, E; // No. of vertices & Edges respectively
    private LinkedList<Integer> adj[]; // Adjacency List
 
    // Count is number of biconnected components. time is
    // used to find discovery times
    static int count = 0, time = 0;
 
    class Edge {
        int u;
        int v;
        Edge(int u, int v)
        {
            this.u = u;
            this.v = v;
        }
    };
 
    // Constructor
    Graph(int v)
    {
        V = v;
        E = 0;
        adj = new LinkedList[v];
        for (int i = 0; i < v; ++i)
            adj[i] = new LinkedList();
    }
 
    // Function to add an edge into the graph
    void addEdge(int v, int w)
    {
        adj[v].add(w);
        E++;
    }
 
    // A recursive function that finds and prints strongly connected
    // components using DFS traversal
    // u --> The vertex to be visited next
    // disc[] --> Stores discovery times of visited vertices
    // low[] -- >> earliest visited vertex (the vertex with minimum
    // discovery time) that can be reached from subtree
    // rooted with current vertex
    // *st -- >> To store visited edges
    void BCCUtil(int u, int disc[], int low[], LinkedList<Edge> st,
                 int parent[])
    {
 
        // Initialize discovery time and low value
        disc[u] = low[u] = ++time;
        int children = 0;
 
        // Go through all vertices adjacent to this
        Iterator<Integer> it = adj[u].iterator();
        while (it.hasNext()) {
            int v = it.next(); // v is current adjacent of 'u'
 
            // If v is not visited yet, then recur for it
            if (disc[v] == -1) {
                children++;
                parent[v] = u;
 
                // store the edge in stack
                st.add(new Edge(u, v));
                BCCUtil(v, disc, low, st, parent);
 
                // Check if the subtree rooted with 'v' has a
                // connection to one of the ancestors of 'u'
                // Case 1 -- per Strongly Connected Components Article
                if (low[u] > low[v])
                    low[u] = low[v];
 
                // If u is an articulation point,
                // pop all edges from stack till u -- v
                if ((disc[u] == 1 && children > 1) || (disc[u] > 1 && low[v] >= disc[u])) {
                    while (st.getLast().u != u || st.getLast().v != v) {
                        System.out.print(st.getLast().u + "--" + st.getLast().v + " ");
                        st.removeLast();
                    }
                    System.out.println(st.getLast().u + "--" + st.getLast().v + " ");
                    st.removeLast();
 
                    count++;
                }
            }
 
            // Update low value of 'u' only if 'v' is still in stack
            // (i.e. it's a back edge, not cross edge).
            // Case 2 -- per Strongly Connected Components Article
            else if (v != parent[u] && disc[v] < disc[u] ) {
                if (low[u] > disc[v])
                    low[u] = disc[v];
 
                st.add(new Edge(u, v));
            }
        }
    }
 
    // The function to do DFS traversal. It uses BCCUtil()
    void BCC()
    {
        int disc[] = new int[V];
        int low[] = new int[V];
        int parent[] = new int[V];
        LinkedList<Edge> st = new LinkedList<Edge>();
 
        // Initialize disc and low, and parent arrays
        for (int i = 0; i < V; i++) {
            disc[i] = -1;
            low[i] = -1;
            parent[i] = -1;
        }
 
        for (int i = 0; i < V; i++) {
            if (disc[i] == -1)
                BCCUtil(i, disc, low, st, parent);
 
            int j = 0;
 
            // If stack is not empty, pop all edges from stack
            while (st.size() > 0) {
                j = 1;
                System.out.print(st.getLast().u + "--" + st.getLast().v + " ");
                st.removeLast();
            }
            if (j == 1) {
                System.out.println();
                count++;
            }
        }
    }
 
    public static void main(String args[])
    {
        Graph g = new Graph(12);
        g.addEdge(0, 1);
        g.addEdge(1, 0);
        g.addEdge(1, 2);
        g.addEdge(2, 1);
        g.addEdge(1, 3);
        g.addEdge(3, 1);
        g.addEdge(2, 3);
        g.addEdge(3, 2);
        g.addEdge(2, 4);
        g.addEdge(4, 2);
        g.addEdge(3, 4);
        g.addEdge(4, 3);
        g.addEdge(1, 5);
        g.addEdge(5, 1);
        g.addEdge(0, 6);
        g.addEdge(6, 0);
        g.addEdge(5, 6);
        g.addEdge(6, 5);
        g.addEdge(5, 7);
        g.addEdge(7, 5);
        g.addEdge(5, 8);
        g.addEdge(8, 5);
        g.addEdge(7, 8);
        g.addEdge(8, 7);
        g.addEdge(8, 9);
        g.addEdge(9, 8);
        g.addEdge(10, 11);
        g.addEdge(11, 10);
 
        g.BCC();
 
        System.out.println("Above are " + g.count + " biconnected components in graph");
    }
}
// This code is contributed by Aakash Hasija


Python3




# Python program to find biconnected components in a given
# undirected graph
# Complexity : O(V + E)
 
  
from collections import defaultdict
  
# This class represents an directed graph
# using adjacency list representation
class Graph:
  
    def __init__(self, vertices):
        # No. of vertices
        self.V = vertices
         
        # default dictionary to store graph
        self.graph = defaultdict(list)
         
        # time is used to find discovery times
        self.Time = 0
         
        # Count is number of biconnected components
        self.count = 0
  
    # function to add an edge to graph
    def addEdge(self, u, v):
        self.graph[u].append(v)
        self.graph[v].append(u)
 
    '''A recursive function that finds and prints strongly connected
    components using DFS traversal
    u --> The vertex to be visited next
    disc[] --> Stores discovery times of visited vertices
    low[] -- >> earliest visited vertex (the vertex with minimum
               discovery time) that can be reached from subtree
               rooted with current vertex
    st -- >> To store visited edges'''
    def BCCUtil(self, u, parent, low, disc, st):
 
        # Count of children in current node
        children = 0
 
        # Initialize discovery time and low value
        disc[u] = self.Time
        low[u] = self.Time
        self.Time += 1
 
 
        # Recur for all the vertices adjacent to this vertex
        for v in self.graph[u]:
            # If v is not visited yet, then make it a child of u
            # in DFS tree and recur for it
            if disc[v] == -1 :
                parent[v] = u
                children += 1
                st.append((u, v)) # store the edge in stack
                self.BCCUtil(v, parent, low, disc, st)
 
                # Check if the subtree rooted with v has a connection to
                # one of the ancestors of u
                # Case 1 -- per Strongly Connected Components Article
                low[u] = min(low[u], low[v])
 
                # If u is an articulation point, pop
                # all edges from stack till (u, v)
                if parent[u] == -1 and children > 1 or parent[u] != -1 and low[v] >= disc[u]:
                    self.count += 1 # increment count
                    w = -1
                    while w != (u, v):
                        w = st.pop()
                        print(w,end=" ")
                    print()
             
            elif v != parent[u] and low[u] > disc[v]:
                '''Update low value of 'u' only of 'v' is still in stack
                (i.e. it's a back edge, not cross edge).
                Case 2
                -- per Strongly Connected Components Article'''
 
                low[u] = min(low [u], disc[v])
     
                st.append((u, v))
 
 
    # The function to do DFS traversal.
    # It uses recursive BCCUtil()
    def BCC(self):
         
        # Initialize disc and low, and parent arrays
        disc = [-1] * (self.V)
        low = [-1] * (self.V)
        parent = [-1] * (self.V)
        st = []
 
        # Call the recursive helper function to
        # find articulation points
        # in DFS tree rooted with vertex 'i'
        for i in range(self.V):
            if disc[i] == -1:
                self.BCCUtil(i, parent, low, disc, st)
 
            # If stack is not empty, pop all edges from stack
            if st:
                self.count = self.count + 1
 
                while st:
                    w = st.pop()
                    print(w,end=" ")
                print ()
 
# Create a graph given in the above diagram
 
g = Graph(12)
g.addEdge(0, 1)
g.addEdge(1, 2)
g.addEdge(1, 3)
g.addEdge(2, 3)
g.addEdge(2, 4)
g.addEdge(3, 4)
g.addEdge(1, 5)
g.addEdge(0, 6)
g.addEdge(5, 6)
g.addEdge(5, 7)
g.addEdge(5, 8)
g.addEdge(7, 8)
g.addEdge(8, 9)
g.addEdge(10, 11)
 
g.BCC();
print ("Above are % d biconnected components in graph" %(g.count));
 
# This code is contributed by Neelam Yadav


C#




// A C# program to find biconnected components in a given
// undirected graph
using System;
using System.Collections.Generic;
 
// This class represents a directed graph using adjacency
// list representation
public class Graph
{
    private int V, E; // No. of vertices & Edges respectively
    private List<int> []adj; // Adjacency List
 
    // Count is number of biconnected components. time is
    // used to find discovery times
    int count = 0, time = 0;
 
    class Edge
    {
        public int u;
        public int v;
        public Edge(int u, int v)
        {
            this.u = u;
            this.v = v;
        }
    };
 
    // Constructor
    public Graph(int v)
    {
        V = v;
        E = 0;
        adj = new List<int>[v];
        for (int i = 0; i < v; ++i)
            adj[i] = new List<int>();
    }
 
    // Function to add an edge into the graph
    void addEdge(int v, int w)
    {
        adj[v].Add(w);
        E++;
    }
 
    // A recursive function that finds and prints strongly connected
    // components using DFS traversal
    // u --> The vertex to be visited next
    // disc[] --> Stores discovery times of visited vertices
    // low[] -- >> earliest visited vertex (the vertex with minimum
    // discovery time) that can be reached from subtree
    // rooted with current vertex
    // *st -- >> To store visited edges
    void BCCUtil(int u, int []disc, int []low, List<Edge> st,
                int []parent)
    {
 
        // Initialize discovery time and low value
        disc[u] = low[u] = ++time;
        int children = 0;
 
        // Go through all vertices adjacent to this
        foreach(int it in adj[u])
        {
            int v = it; // v is current adjacent of 'u'
 
            // If v is not visited yet, then recur for it
            if (disc[v] == -1)
            {
                children++;
                parent[v] = u;
 
                // store the edge in stack
                st.Add(new Edge(u, v));
                BCCUtil(v, disc, low, st, parent);
 
                // Check if the subtree rooted with 'v' has a
                // connection to one of the ancestors of 'u'
                // Case 1 -- per Strongly Connected Components Article
                if (low[u] > low[v])
                    low[u] = low[v];
 
                // If u is an articulation point,
                // pop all edges from stack till u -- v
                if ((disc[u] == 1 && children > 1) ||
                    (disc[u] > 1 && low[v] >= disc[u]))
                {
                    while (st[st.Count-1].u != u ||
                           st[st.Count-1].v != v)
                    {
                        Console.Write(st[st.Count - 1].u + "--" +
                                      st[st.Count - 1].v + " ");
                        st.RemoveAt(st.Count - 1);
                    }
                    Console.WriteLine(st[st.Count - 1].u + "--" +
                                       st[st.Count - 1].v + " ");
                    st.RemoveAt(st.Count - 1);
 
                    count++;
                }
            }
 
            // Update low value of 'u' only if 'v' is still in stack
            // (i.e. it's a back edge, not cross edge).
            // Case 2 -- per Strongly Connected Components Article
            else if (v != parent[u] && disc[v] < disc[u] )
            {
                if (low[u] > disc[v])
                    low[u] = disc[v];
 
                st.Add(new Edge(u, v));
            }
        }
    }
 
    // The function to do DFS traversal. It uses BCCUtil()
    void BCC()
    {
        int []disc = new int[V];
        int []low = new int[V];
        int []parent = new int[V];
        List<Edge> st = new List<Edge>();
 
        // Initialize disc and low, and parent arrays
        for (int i = 0; i < V; i++)
        {
            disc[i] = -1;
            low[i] = -1;
            parent[i] = -1;
        }
 
        for (int i = 0; i < V; i++)
        {
            if (disc[i] == -1)
                BCCUtil(i, disc, low, st, parent);
 
            int j = 0;
 
            // If stack is not empty, pop all edges from stack
            while (st.Count > 0)
            {
                j = 1;
                Console.Write(st[st.Count - 1].u + "--" +
                            st[st.Count - 1].v + " ");
                st.RemoveAt(st.Count - 1);
            }
            if (j == 1)
            {
                Console.WriteLine();
                count++;
            }
        }
    }
 
    // Driver code
    public static void Main(String []args)
    {
        Graph g = new Graph(12);
        g.addEdge(0, 1);
        g.addEdge(1, 0);
        g.addEdge(1, 2);
        g.addEdge(2, 1);
        g.addEdge(1, 3);
        g.addEdge(3, 1);
        g.addEdge(2, 3);
        g.addEdge(3, 2);
        g.addEdge(2, 4);
        g.addEdge(4, 2);
        g.addEdge(3, 4);
        g.addEdge(4, 3);
        g.addEdge(1, 5);
        g.addEdge(5, 1);
        g.addEdge(0, 6);
        g.addEdge(6, 0);
        g.addEdge(5, 6);
        g.addEdge(6, 5);
        g.addEdge(5, 7);
        g.addEdge(7, 5);
        g.addEdge(5, 8);
        g.addEdge(8, 5);
        g.addEdge(7, 8);
        g.addEdge(8, 7);
        g.addEdge(8, 9);
        g.addEdge(9, 8);
        g.addEdge(10, 11);
        g.addEdge(11, 10);
 
        g.BCC();
 
        Console.WriteLine("Above are " + g.count +
                        " biconnected components in graph");
    }
}
 
// This code is contributed by PrinciRaj1992


Javascript




<script>
// A Javascript program to find biconnected components in a given
// undirected graph
 
class Edge
{
    constructor(u,v)
    {
        this.u = u;
            this.v = v;
    }
}
 
// This class represents a directed graph using adjacency
// list representation
class Graph
{
    // Constructor
    constructor(v)
    {
        this.count=0;
        this.time = 0;
        this.V = v;
        this.E = 0;
        this.adj = new Array(v);
        for (let i = 0; i < v; ++i)
            this.adj[i] = [];
    }
     
    // Function to add an edge into the graph
    addEdge(v,w)
    {
        this.adj[v].push(w);
        this.E++;
    }
     
    // A recursive function that finds and prints strongly connected
    // components using DFS traversal
    // u --> The vertex to be visited next
    // disc[] --> Stores discovery times of visited vertices
    // low[] -- >> earliest visited vertex (the vertex with minimum
    // discovery time) that can be reached from subtree
    // rooted with current vertex
    // *st -- >> To store visited edges
    BCCUtil(u,disc,low,st,parent)
    {
        // Initialize discovery time and low value
        disc[u] = low[u] = ++this.time;
        let children = 0;
   
        // Go through all vertices adjacent to this
         
        for(let it of this.adj[u].values()) {
            let v = it; // v is current adjacent of 'u'
   
            // If v is not visited yet, then recur for it
            if (disc[v] == -1) {
                children++;
                parent[v] = u;
   
                // store the edge in stack
                st.push(new Edge(u, v));
                this.BCCUtil(v, disc, low, st, parent);
   
                // Check if the subtree rooted with 'v' has a
                // connection to one of the ancestors of 'u'
                // Case 1 -- per Strongly Connected Components Article
                if (low[u] > low[v])
                    low[u] = low[v];
   
                // If u is an articulation point,
                // pop all edges from stack till u -- v
                if ((disc[u] == 1 && children > 1) || (disc[u] > 1 && low[v] >= disc[u])) {
                    while (st[st.length-1].u != u || st[st.length-1].v != v) {
                        document.write(st[st.length-1].u + "--" + st[st.length-1].v + " ");
                        st.pop();
                    }
                    document.write(st[st.length-1].u + "--" + st[st.length-1].v + " <br>");
                    st.pop();
   
                    this.count++;
                }
            }
   
            // Update low value of 'u' only if 'v' is still in stack
            // (i.e. it's a back edge, not cross edge).
            // Case 2 -- per Strongly Connected Components Article
            else if (v != parent[u] && disc[v] < disc[u] ) {
                if (low[u] > disc[v])
                    low[u] = disc[v];
   
                st.push(new Edge(u, v));
            }
        }
    }
     
    // The function to do DFS traversal. It uses BCCUtil()
    BCC()
    {
        let disc = new Array(this.V);
        let low = new Array(this.V);
        let parent = new Array(this.V);
        let st = [];
   
        // Initialize disc and low, and parent arrays
        for (let i = 0; i < this.V; i++) {
            disc[i] = -1;
            low[i] = -1;
            parent[i] = -1;
        }
   
        for (let i = 0; i < this.V; i++) {
            if (disc[i] == -1)
                this.BCCUtil(i, disc, low, st, parent);
   
            let j = 0;
   
            // If stack is not empty, pop all edges from stack
            while (st.length > 0) {
                j = 1;
                document.write(st[st.length-1].u + "--" + st[st.length-1].v + " ");
                st.pop();
            }
            if (j == 1) {
                document.write("<br>");
                this.count++;
            }
    }
}
}
 
let g = new Graph(12);
g.addEdge(0, 1);
g.addEdge(1, 0);
g.addEdge(1, 2);
g.addEdge(2, 1);
g.addEdge(1, 3);
g.addEdge(3, 1);
g.addEdge(2, 3);
g.addEdge(3, 2);
g.addEdge(2, 4);
g.addEdge(4, 2);
g.addEdge(3, 4);
g.addEdge(4, 3);
g.addEdge(1, 5);
g.addEdge(5, 1);
g.addEdge(0, 6);
g.addEdge(6, 0);
g.addEdge(5, 6);
g.addEdge(6, 5);
g.addEdge(5, 7);
g.addEdge(7, 5);
g.addEdge(5, 8);
g.addEdge(8, 5);
g.addEdge(7, 8);
g.addEdge(8, 7);
g.addEdge(8, 9);
g.addEdge(9, 8);
g.addEdge(10, 11);
g.addEdge(11, 10);
 
g.BCC();
 
document.write("Above are " + g.count + " biconnected components in graph");
 
// This code is contributed by avanitrachhadiya2155
</script>


Output

4--2 3--4 3--1 2--3 1--2
8--9
8--5 7--8 5--7
6--0 5--6 1--5 0--1 
10--11
Above are 5 biconnected components in graph

Time Complexity : O(N + E), where N is the number of nodes and E is the number of edges, as the time complexity of Depth first search.
Space Complexity :O(N), here N is the number of nodes in the graph, we need a O(N) recursion stack space to make DFS calls. 



Previous Article
Next Article

Similar Reads

Biconnected graph
An undirected graph is called Biconnected if there are two vertex-disjoint paths between any two vertices. In a Biconnected Graph, there is a simple cycle through any two vertices. By convention, two nodes connected by an edge form a biconnected graph, but this does not verify the above properties. For a graph with more than two vertices, the above
15+ min read
Number of connected components in a doubly linked list
Given a doubly linked list ‘L’ and an array ‘refArr’ of references to the nodes of the doubly linked list ‘L’. Array 'refArr' does not contain any duplicate references and the references are not ORDERED. m &lt;= total no. of nodes in the doubly linked list where m = size of the reference array. The task is to find the total number of connected comp
15+ min read
Maximum number of edges among all connected components of an undirected graph
Given integers 'N' and 'K' where, N is the number of vertices of an undirected graph and 'K' denotes the number of edges in the same graph (each edge is denoted by a pair of integers where i, j means that the vertex 'i' is directly connected to the vertex 'j' in the graph). The task is to find the maximum number of edges among all the connected com
6 min read
Clone an undirected graph with multiple connected components
Given an undirected graph with multiple connected components, the task is to clone the graph. Cloning a graph with a single connected component can be seen here. Examples: An example of an undirected graph with 3 connected components: Approach: The idea is to follow the same approach posted for cloning connected graph, but with every node so that w
15 min read
Number of connected components in a 2-D matrix of strings
Given a 2-D matrix mat[][] the task is to count the number of connected components in the matrix. A connected component is formed by all equal elements that share some common side with at least one other element of the same component.Examples: Input: mat[][] = {"bbba", "baaa"} Output: 2 The two connected components are: bbb b AND a aaa Input: mat[]
8 min read
Program to count Number of connected components in an undirected graph
Given an undirected graph g, the task is to print the number of connected components in the graph. Examples: Input: Output: 3 There are three connected components: 1 - 5, 0 - 2 - 4 and 3 Approach: DFS visit all the connected vertices of the given vertex. When iterating over all vertices, whenever we see unvisited node, it is because it was not visi
6 min read
Check if a Tree can be split into K equal connected components
Given Adjacency List representation of a tree and an integer K., the task is to find whether the given tree can be split into K equal Connected Components or not.Note: Two connected components are said to be equal if they contain equal number of nodes. Examples: Input: N = 15, K = 5 Below is the given tree with Number nodes = 15 Output: YES Explana
9 min read
Check if the length of all connected components is a Fibonacci number
Given an undirected graph with V vertices and E edges, the task is to find all the connected components of the graph and check if each of their lengths are a Fibonacci number or not. For example, consider the following graph. As depicted above, the lengths of the connected components are 2, 3, and 2 which are Fibonacci numbers. Examples: Input: E =
15+ min read
Count of unique lengths of connected components for an undirected graph using STL
Given an undirected graph, the task is to find the size of each connected component and print the number of unique sizes of connected components As depicted above, the count(size of the connected component) associated with the connected components is 2, 3, and 2. Now, the unique count of the components is 2 and 3. Hence, the expected result is Coun
10 min read
Maximum decimal equivalent possible among all connected components of a Binary Valued Graph
Given a binary-valued Undirected Graph with V vertices and E edges, the task is to find the maximum decimal equivalent among all the connected components of the graph. A binary-valued graph can be considered as having only binary numbers (0 or 1) as the vertex values. Examples: Input: E = 4, V = 7 Output: 3 Explanation: Decimal equivalents of the c
14 min read
Article Tags :
Practice Tags :