Given an undirected graph, The task is to check if there is a cycle in the given graph.
Example:
Input: N = 4, E = 4

Output: Yes
Explanation: The diagram clearly shows a cycle 0 to 2 to 1 to 0
Input: N = 4, E = 3 , 0 1, 1 2, 2 3

Output: No
Explanation: There is no cycle in the given graph
Articles about cycle detection:
Find cycle in undirected Graph using DFS:
Use DFS from every unvisited node. Depth First Traversal can be used to detect a cycle in a Graph. There is a cycle in a graph only if there is a back edge present in the graph. A back edge is an edge that is indirectly joining a node to itself (self-loop) or one of its ancestors in the tree produced by DFS.
To find the back edge to any of its ancestors keep a visited array and if there is a back edge to any visited node then there is a loop and return true.
Follow the below steps to implement the above approach:
- Iterate over all the nodes of the graph and Keep a visited array visited[] to track the visited nodes.
- Run a Depth First Traversal on the given subgraph connected to the current node and pass the parent of the current node. In each recursive
- Set visited[root] as 1.
- Iterate over all adjacent nodes of the current node in the adjacency list
- If it is not visited then run DFS on that node and return true if it returns true.
- Else if the adjacent node is visited and not the parent of the current node then return true.
- Return false.
Dry Run:

Another possible scenario:
If No cycle is detected after running Depth First Traversal for every subgraph the there exists no cycle as shown below

Graph with disconnected components
Below is the implementation of the above approach:
C++
#include <iostream>
#include <limits.h>
#include <list>
using namespace std;
class Graph {
int V;
list< int >* adj;
bool isCyclicUtil( int v, bool visited[], int parent);
public :
Graph( int V);
void addEdge( int v, int w);
bool isCyclic();
};
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);
}
bool Graph::isCyclicUtil( int v, bool visited[], int parent)
{
visited[v] = true ;
list< int >::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i) {
if (!visited[*i]) {
if (isCyclicUtil(*i, visited, v))
return true ;
}
else if (*i != parent)
return true ;
}
return false ;
}
bool Graph::isCyclic()
{
bool * visited = new bool [V];
for ( int i = 0; i < V; i++)
visited[i] = false ;
for ( int u = 0; u < V; u++) {
if (!visited[u])
if (isCyclicUtil(u, visited, -1))
return true ;
}
return false ;
}
int main()
{
Graph g1(5);
g1.addEdge(1, 0);
g1.addEdge(0, 2);
g1.addEdge(2, 1);
g1.addEdge(0, 3);
g1.addEdge(3, 4);
g1.isCyclic() ? cout << "Graph contains cycle\n"
: cout << "Graph doesn't contain cycle\n" ;
Graph g2(3);
g2.addEdge(0, 1);
g2.addEdge(1, 2);
g2.isCyclic() ? cout << "Graph contains cycle\n"
: cout << "Graph doesn't contain cycle\n" ;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
@SuppressWarnings ( "unchecked" )
class Graph {
private int V;
private LinkedList<Integer> adj[];
Graph( int v)
{
V = v;
adj = new LinkedList[v];
for ( int i = 0 ; i < v; ++i)
adj[i] = new LinkedList();
}
void addEdge( int v, int w)
{
adj[v].add(w);
adj[w].add(v);
}
Boolean isCyclicUtil( int v, Boolean visited[],
int parent)
{
visited[v] = true ;
Integer i;
Iterator<Integer> it = adj[v].iterator();
while (it.hasNext()) {
i = it.next();
if (!visited[i]) {
if (isCyclicUtil(i, visited, v))
return true ;
}
else if (i != parent)
return true ;
}
return false ;
}
Boolean isCyclic()
{
Boolean visited[] = new Boolean[V];
for ( int i = 0 ; i < V; i++)
visited[i] = false ;
for ( int u = 0 ; u < V; u++) {
if (!visited[u])
if (isCyclicUtil(u, visited, - 1 ))
return true ;
}
return false ;
}
public static void main(String args[])
{
Graph g1 = new Graph( 5 );
g1.addEdge( 1 , 0 );
g1.addEdge( 0 , 2 );
g1.addEdge( 2 , 1 );
g1.addEdge( 0 , 3 );
g1.addEdge( 3 , 4 );
if (g1.isCyclic())
System.out.println( "Graph contains cycle" );
else
System.out.println( "Graph doesn't contain cycle" );
Graph g2 = new Graph( 3 );
g2.addEdge( 0 , 1 );
g2.addEdge( 1 , 2 );
if (g2.isCyclic())
System.out.println( "Graph contains cycle" );
else
System.out.println( "Graph doesn't contain cycle" );
}
}
|
Python3
from collections import defaultdict
class Graph:
def __init__( self , vertices):
self .V = vertices
self .graph = defaultdict( list )
def addEdge( self , v, w):
self .graph[v].append(w)
self .graph[w].append(v)
def isCyclicUtil( self , v, visited, parent):
visited[v] = True
for i in self .graph[v]:
if visited[i] = = False :
if ( self .isCyclicUtil(i, visited, v)):
return True
elif parent ! = i:
return True
return False
def isCyclic( self ):
visited = [ False ] * ( self .V)
for i in range ( self .V):
if visited[i] = = False :
if ( self .isCyclicUtil
(i, visited, - 1 )) = = True :
return True
return False
g = Graph( 5 )
g.addEdge( 1 , 0 )
g.addEdge( 1 , 2 )
g.addEdge( 2 , 0 )
g.addEdge( 0 , 3 )
g.addEdge( 3 , 4 )
if g.isCyclic():
print ( "Graph contains cycle" )
else :
print ( "Graph doesn't contain cycle " )
g1 = Graph( 3 )
g1.addEdge( 0 , 1 )
g1.addEdge( 1 , 2 )
if g1.isCyclic():
print ( "Graph contains cycle" )
else :
print ( "Graph doesn't contain cycle " )
|
C#
using System;
using System.Collections.Generic;
class Graph {
private int V;
private List< int >[] adj;
Graph( int v)
{
V = v;
adj = new List< int >[ v ];
for ( int i = 0; i < v; ++i)
adj[i] = new List< int >();
}
void addEdge( int v, int w)
{
adj[v].Add(w);
adj[w].Add(v);
}
Boolean isCyclicUtil( int v, Boolean[] visited,
int parent)
{
visited[v] = true ;
foreach ( int i in adj[v])
{
if (!visited[i]) {
if (isCyclicUtil(i, visited, v))
return true ;
}
else if (i != parent)
return true ;
}
return false ;
}
Boolean isCyclic()
{
Boolean[] visited = new Boolean[V];
for ( int i = 0; i < V; i++)
visited[i] = false ;
for ( int u = 0; u < V; u++)
if (!visited[u])
if (isCyclicUtil(u, visited, -1))
return true ;
return false ;
}
public static void Main(String[] args)
{
Graph g1 = new Graph(5);
g1.addEdge(1, 0);
g1.addEdge(0, 2);
g1.addEdge(2, 1);
g1.addEdge(0, 3);
g1.addEdge(3, 4);
if (g1.isCyclic())
Console.WriteLine( "Graph contains cycle" );
else
Console.WriteLine(
"Graph doesn't contain cycle" );
Graph g2 = new Graph(3);
g2.addEdge(0, 1);
g2.addEdge(1, 2);
if (g2.isCyclic())
Console.WriteLine( "Graph contains cycle" );
else
Console.WriteLine(
"Graph doesn't contain cycle" );
}
}
|
Javascript
class Graph{
constructor(vertices){
this .V = vertices;
this .graph = new Array(vertices);
for (let i = 0; i < vertices; i++){
this .graph[i] = new Array();
}
}
addEdge(v, w){
this .graph[v].push(w);
this .graph[w].push(v);
}
isCyclicUtil(v, visited, parent){
visited[v] = true ;
for (let i = 0; i < this .graph[v].length; i++){
if (visited[ this .graph[v][i]] == false ){
if ( this .isCyclicUtil( this .graph[v][i], visited, v) == true ){
return true ;
}
}
else if (parent != this .graph[v][i]){
return true ;
}
}
return false ;
}
isCyclic(){
let visited = new Array( this .V).fill( false );
for (let i = 0; i < this .V; i++){
if (visited[i] == false ){
if ( this .isCyclicUtil(i, visited, -1) == true ){
return true ;
}
}
}
return false ;
}
}
let g = new Graph(5);
g.addEdge(1, 0);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(0, 3);
g.addEdge(3, 4);
if (g.isCyclic() == true ){
console.log( "Graph contains cycle" );
}
else {
console.log( "Graph doesn't contain cycle " );
}
let g1 = new Graph(3);
g1.addEdge(0, 1);
g1.addEdge(1, 2);
if (g1.isCyclic() == true ){
console.log( "Graph contains cycle" );
}
else {
console.log( "Graph doesn't contain cycle " );
}
|
Output
Graph contains cycle
Graph doesn't contain cycle
Time Complexity: O(V+E), The program does a simple DFS Traversal of the graph which is represented using an adjacency list. So the time complexity is O(V+E).
Auxiliary Space: O(V), To store the visited array O(V) space is required.
Exercise: Can we use BFS to detect cycle in an undirected graph in O(V+E) time? What about directed graphs?
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!