 Open in App
Not now

# Check if a given Graph is 2-edge connected or not

• Difficulty Level : Medium
• Last Updated : 26 Jul, 2022

Given an undirected graph G, with V vertices and E edges, the task is to check whether the graph is 2-edge connected or not. A graph is said to be 2-edge connected if, on removing any edge of the graph, it still remains connected, i.e. it contains no Bridges

Examples:

Input: V = 7, E = 9 Output: Yes
Explanation:
Given any vertex in the graph, we can reach any other vertex in the graph. Moreover, removing any edge from the graph does not affect its connectivity. So, the graph is said to be 2-edge connected.

Input: V = 8, E = 9 example2

Output: No
Explanation:
On removal of the edge between vertex 3 and vertex 4, the graph is not connected anymore. So, the graph is not 2-edge connected.

Naive Approach: The Naive approach is to check that on removing any edge X, if the remaining graph G – X is connected or not. If the graph remains connected on removing every edge one by one then it is a 2-edge connected graph. To implement the above idea, remove an edge and perform Depth First Search(DFS) or Breadth-First Search(BFS) from any vertex and check if all vertices are covered or not. Repeat this process for all E edges. If all vertices cannot be traversed for any edge, print No. Otherwise, print Yes

Time Complexity: O(E * ( V + E))
Auxiliary Space: O(1)

Efficient Approach: The idea to solve this problem is:

Bridges in a graph: An edge in an undirected connected graph is a bridge if removing it disconnects the graph. For a disconnected undirected graph, definition is similar, a bridge is an edge removing which increases number of disconnected components.

=> If there is any bridge in the graph then it will never be a 2-edge connected otherwise it will be a 2-edge connected.

Below is the Implementation of the above approach:

## C++

 `// A C++ program to find bridges in a given undirected graph``#include ``#include ``#define NIL -1``using` `namespace` `std;` `// A class that represents an undirected graph``class` `Graph {``    ``int` `V; ``// No. of vertices``    ``list<``int``>* adj; ``// A dynamic array of adjacency lists``    ``void` `bridgeUtil(``int` `v, ``bool` `visited[], ``int` `disc[],``                    ``int` `low[], ``int` `parent[]);` `public``:``    ``int` `count = 0;` `    ``Graph(``int` `V); ``// Constructor``    ``void` `addEdge(``int` `v, ``int` `w); ``// to add an edge to graph``    ``void` `bridge(); ``// prints all bridges``};` `Graph::Graph(``int` `V)``{``    ``this``->V = V;``    ``adj = ``new` `list<``int``>[V];``}` `void` `Graph::addEdge(``int` `v, ``int` `w)``{``    ``adj[v].push_back(w);``    ``adj[w].push_back(v); ``// Note: the graph is undirected``}` `// A recursive function that finds and prints bridges using``// DFS traversal``// u --> The vertex to be visited next``// visited[] --> keeps track of visited vertices``// disc[] --> Stores discovery times of visited vertices``// parent[] --> Stores parent vertices in DFS tree``void` `Graph::bridgeUtil(``int` `u, ``bool` `visited[], ``int` `disc[],``                       ``int` `low[], ``int` `parent[])``{``    ``// A static variable is used for simplicity, we can``    ``// avoid use of static variable by passing a pointer.``    ``static` `int` `time` `= 0;` `    ``// Mark the current node as visited``    ``visited[u] = ``true``;` `    ``// Initialize discovery time and low value``    ``disc[u] = low[u] = ++``time``;` `    ``// 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` `(!visited[v]) {``            ``parent[v] = u;``            ``bridgeUtil(v, visited, disc, low, parent);` `            ``// Check if the subtree rooted with v has a``            ``// connection to one of the ancestors of u``            ``low[u] = min(low[u], low[v]);` `            ``// If the lowest vertex reachable from subtree``            ``// under v is below u in DFS tree, then u-v``            ``// is a bridge``            ``if` `(low[v] > disc[u])``                ``count++;``        ``}` `        ``// Update low value of u for parent function calls.``        ``else` `if` `(v != parent[u])``            ``low[u] = min(low[u], disc[v]);``    ``}``}` `// DFS based function to find all bridges. It uses recursive``// function bridgeUtil()``void` `Graph::bridge()``{``    ``// Mark all the vertices as not visited` `    ``bool``* visited = ``new` `bool``[V];``    ``int``* disc = ``new` `int``[V];``    ``int``* low = ``new` `int``[V];``    ``int``* parent = ``new` `int``[V];` `    ``// Initialize parent and visited arrays``    ``for` `(``int` `i = 0; i < V; i++) {``        ``parent[i] = NIL;``        ``visited[i] = ``false``;``    ``}` `    ``// Call the recursive helper function to find Bridges``    ``// in DFS tree rooted with vertex 'i'``    ``for` `(``int` `i = 0; i < V; i++)``        ``if` `(visited[i] == ``false``)``            ``bridgeUtil(i, visited, disc, low, parent);``}` `// Driver Code``int` `main()``{``    ``Graph g1(6);``    ``g1.addEdge(0, 1);``    ``g1.addEdge(1, 2);``    ``g1.addEdge(2, 0);``    ``g1.addEdge(1, 3);``    ``g1.addEdge(3, 4);``    ``g1.addEdge(4, 5);``    ``g1.addEdge(5, 3);` `    ``g1.bridge();` `    ``if` `(g1.count == 0) {``        ``cout << ``"Given graph is 2-edge connected"``;``    ``}``    ``else` `{``        ``cout << ``"Given graph is not 2-edge connected"``;``    ``}` `    ``return` `0;``}`

## Java

 `// A Java program to find bridges in a given undirected``// graph``import` `java.io.*;``import` `java.util.*;``import` `java.util.LinkedList;` `// This class represents a undirected graph using adjacency``// list representation``class` `Graph {``    ``private` `int` `V; ``// No. of vertices` `    ``// Array of lists for Adjacency List Representation``    ``private` `LinkedList adj[];``    ``int` `time = ``0``;``    ``static` `final` `int` `NIL = -``1``;``    ``static` `int` `count = ``0``;` `    ``// Constructor``    ``@SuppressWarnings``(``"unchecked"``) Graph(``int` `v)``    ``{``        ``V = v;``        ``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); ``// Add w to v's list.``        ``adj[w].add(v); ``// Add v to w's list``    ``}` `    ``// A recursive function that finds and prints bridges``    ``// using DFS traversal``    ``// u --> The vertex to be visited next``    ``// visited[] --> keeps track of visited vertices``    ``// disc[] --> Stores discovery times of visited vertices``    ``// parent[] --> Stores parent vertices in DFS tree``    ``void` `bridgeUtil(``int` `u, ``boolean` `visited[], ``int` `disc[],``                    ``int` `low[], ``int` `parent[])``    ``{` `        ``// Mark the current node as visited``        ``visited[u] = ``true``;` `        ``// Initialize discovery time and low value``        ``disc[u] = low[u] = ++time;` `        ``// Go through all vertices adjacent to this``        ``Iterator i = adj[u].iterator();``        ``while` `(i.hasNext()) {``            ``int` `v = i.next(); ``// v is current adjacent of u` `            ``// If v is not visited yet, then make it a child``            ``// of u in DFS tree and recur for it.``            ``// If v is not visited yet, then recur for it``            ``if` `(!visited[v]) {``                ``parent[v] = u;``                ``bridgeUtil(v, visited, disc, low, parent);` `                ``// Check if the subtree rooted with v has a``                ``// connection to one of the ancestors of u``                ``low[u] = Math.min(low[u], low[v]);` `                ``// If the lowest vertex reachable from``                ``// subtree under v is below u in DFS tree,``                ``// then u-v is a bridge``                ``if` `(low[v] > disc[u])``                    ``count++;``            ``}` `            ``// Update low value of u for parent function``            ``// calls.``            ``else` `if` `(v != parent[u])``                ``low[u] = Math.min(low[u], disc[v]);``        ``}``    ``}` `    ``// DFS based function to find all bridges. It uses``    ``// recursive function bridgeUtil()``    ``void` `bridge()``    ``{``        ``// Mark all the vertices as not visited``        ``boolean` `visited[] = ``new` `boolean``[V];``        ``int` `disc[] = ``new` `int``[V];``        ``int` `low[] = ``new` `int``[V];``        ``int` `parent[] = ``new` `int``[V];` `        ``// Initialize parent and visited, and``        ``// ap(articulation point) arrays``        ``for` `(``int` `i = ``0``; i < V; i++) {``            ``parent[i] = NIL;``            ``visited[i] = ``false``;``        ``}` `        ``// Call the recursive helper function to find``        ``// Bridges in DFS tree rooted with vertex 'i'``        ``for` `(``int` `i = ``0``; i < V; i++)``            ``if` `(visited[i] == ``false``)``                ``bridgeUtil(i, visited, disc, low, parent);``    ``}` `    ``public` `static` `void` `main(String args[])``    ``{``        ``// Create graphs given in above diagrams``        ``System.out.println(``"Bridges in first graph "``);` `        ``Graph g1 = ``new` `Graph(``6``);``        ``g1.addEdge(``0``, ``1``);``        ``g1.addEdge(``1``, ``2``);``        ``g1.addEdge(``2``, ``0``);``        ``g1.addEdge(``1``, ``3``);``        ``g1.addEdge(``3``, ``4``);``        ``g1.addEdge(``4``, ``5``);``        ``g1.addEdge(``5``, ``3``);` `        ``g1.bridge();``        ``if` `(g1.count == ``0``) {``            ``System.out.println(``                ``"Given graph is 2-edge connected:"``);``        ``}``        ``else` `{``            ``System.out.println(``                ``"Given graph is not 2-edge connected:"``);``        ``}``    ``}``}``// This code is contributed by Aakash Hasija`

## Python3

 `# Python program to find bridges in a given undirected graph``# Complexity : O(V+E)` `from` `collections ``import` `defaultdict` `# This class represents an undirected graph using adjacency list representation`  `class` `Graph:``    ``count ``=` `0` `    ``def` `__init__(``self``, vertices):``        ``self``.V ``=` `vertices  ``# No. of vertices``        ``self``.graph ``=` `defaultdict(``list``)  ``# default dictionary to store graph``        ``self``.Time ``=` `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 bridges``    ``using DFS traversal``    ``u --> The vertex to be visited next``    ``visited[] --> keeps track of visited vertices``    ``disc[] --> Stores discovery times of visited vertices``    ``parent[] --> Stores parent vertices in DFS tree'''` `    ``def` `bridgeUtil(``self``, u, visited, parent, low, disc):` `        ``# Mark the current node as visited and print it``        ``visited[u] ``=` `True` `        ``# Initialize discovery time and low value``        ``disc[u] ``=` `self``.Time``        ``low[u] ``=` `self``.Time``        ``self``.Time ``+``=` `1``    ``# count = 0` `        ``# 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` `visited[v] ``=``=` `False``:``                ``parent[v] ``=` `u``                ``self``.bridgeUtil(v, visited, parent, low, disc)` `                ``# Check if the subtree rooted with v has a connection to``                ``# one of the ancestors of u``                ``low[u] ``=` `min``(low[u], low[v])` `                ``''' If the lowest vertex reachable from subtree``                ``under v is below u in DFS tree, then u-v is``                ``a bridge'''``                ``if` `low[v] > disc[u]:``                    ``self``.count ``+``=` `1` `            ``# Update low value of u for parent function calls.``            ``elif` `v !``=` `parent[u]:``                ``low[u] ``=` `min``(low[u], disc[v])` `    ``# DFS based function to find all bridges. It uses recursive``    ``# function bridgeUtil()` `    ``def` `bridge(``self``):` `        ``# Mark all the vertices as not visited and Initialize parent and visited,``        ``# and ap(articulation point) arrays``        ``visited ``=` `[``False``] ``*` `(``self``.V)``        ``disc ``=` `[``float``(``"Inf"``)] ``*` `(``self``.V)``        ``low ``=` `[``float``(``"Inf"``)] ``*` `(``self``.V)``        ``parent ``=` `[``-``1``] ``*` `(``self``.V)` `        ``# Call the recursive helper function to find bridges``        ``# in DFS tree rooted with vertex 'i'``        ``for` `i ``in` `range``(``self``.V):``            ``if` `visited[i] ``=``=` `False``:``                ``self``.bridgeUtil(i, visited, parent, low, disc)`  `# Create a graph given in the above diagram``g1 ``=` `Graph(``6``)``g1.addEdge(``0``, ``1``)``g1.addEdge(``1``, ``2``)``g1.addEdge(``2``, ``0``)``g1.addEdge(``1``, ``3``)``g1.addEdge(``3``, ``4``)``g1.addEdge(``4``, ``5``)``g1.addEdge(``5``, ``3``)` `g1.bridge()` `if` `g1.count ``=``=` `0``:``    ``print``(``"Given graph is 2-edge connected"``)``else``:``    ``print``(``"Given graph is not 2-edge connected"``)`  `# This code is contributed by Neelam Yadav`

Output

`Given graph is not 2-edge connected`

Time Complexity: O(V + E)
Auxiliary Space: O(V)

My Personal Notes arrow_drop_up