# Biconnected Components

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.

`              `

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)
{
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] && disc[v] < low[u])
{
low[u]  = min(low[u], disc[v]);
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.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

// 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;
for (int i=0; i<v; ++i)
}

//Function to add an edge into the graph
void addEdge(int v,int 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
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 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] && disc[v] < low[u])
{
if (low[u]>disc[v])
low[u]=disc[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];

// 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.BCC();

System.out.println("Above are " + g.count +
" biconnected components in graph");
}
}
// This code is contributed by Aakash Hasija
```

## Python

```# 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
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,
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,
print ""

# Create a graph given in the above diagram

g = Graph(12)

g.BCC();
print ("Above are %d biconnected components in graph" %(g.count));

#This code is contributed by Neelam Yadav
```

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
```

# GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.
4.2 Average Difficulty : 4.2/5.0
Based on 30 vote(s)

Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.