Given a directed graph with V vertices numbered from 0 to V - 1 and E directed edges. The graph is represented using a 2D array edges[][] of size E, where each entry edges[i] = [u, v] denotes a directed edge from vertex u to vertex v.
Check whether the graph contains any cycle. Return true if there exists at least one cycle in the graph; otherwise, return false.
If Depth First Search (DFS) reaches a vertex that is already present in the current DFS path, a cycle exists.
A vertex may have been visited during an earlier DFS traversal but may not be part of the current DFS path. So using only visited[] is not enough. We also keep track of the vertices currently being explored.
For this, we use two arrays:
visited[]: Marks vertices that have been visited at least once.
recStack[]: Marks vertices that are currently present in the DFS recursion path.
If during DFS we reach a vertex whose recStack[] value is true, a cycle is found.
After completely exploring all adjacent vertices of a node, we remove it from the current DFS path by setting recStack[u] = false. This ensures that recStack[] contains only the vertices that belong to the current DFS path.
C++
#includeusingnamespacestd;booldfs(vector<vector<int>>&adj,intu,vector<bool>&visited,vector<bool>&recStack){// Node is already in the current DFS pathif(recStack[u])returntrue;// Node is already visitedif(visited[u])returnfalse;visited[u]=true;recStack[u]=true;// Visit all adjacent nodesfor(intv:adj[u]){if(dfs(adj,v,visited,recStack))returntrue;}// Remove node from current DFS pathrecStack[u]=false;returnfalse;}boolisCyclic(intV,vector<vector<int>>&edges){vector<vector<int>>adj(V);// Create adjacency listfor(auto&edge:edges){adj[edge[0]].push_back(edge[1]);}vector<bool>visited(V,false);vector<bool>recStack(V,false);// Check all componentsfor(inti=0;i<V;i++){if(!visited[i]&&dfs(adj,i,visited,recStack))returntrue;}returnfalse;}intmain(){intV=4;vector<vector<int>>edges={{0,1},{1,2},{2,0},{2,3}};cout<<(isCyclic(V,edges)?"true":"false")<<endl;return0;}
Java
importjava.util.ArrayList;classGFG{publicstaticbooleandfs(ArrayList<ArrayList<Integer>>adj,intu,boolean[]visited,boolean[]recStack){// Node is already in the current DFS pathif(recStack[u])returntrue;// Node is already visitedif(visited[u])returnfalse;visited[u]=true;recStack[u]=true;// Visit all adjacent nodesfor(intv:adj.get(u)){if(dfs(adj,v,visited,recStack))returntrue;}// Remove node from current DFS pathrecStack[u]=false;returnfalse;}publicstaticbooleanisCyclic(intV,int[][]edges){ArrayList<ArrayList<Integer>>adj=newArrayList<>();for(inti=0;i<V;i++)adj.add(newArrayList<>());// Create adjacency listfor(int[]edge:edges){adj.get(edge[0]).add(edge[1]);}boolean[]visited=newboolean[V];boolean[]recStack=newboolean[V];// Check all componentsfor(inti=0;i<V;i++){if(!visited[i]&&dfs(adj,i,visited,recStack))returntrue;}returnfalse;}publicstaticvoidmain(String[]args){intV=4;int[][]edges={{0,1},{1,2},{2,0},{2,3}};System.out.println(isCyclic(V,edges)?"true":"false");}}
Python
defdfs(adj,u,visited,recStack):# Node is already in the current DFS pathifrecStack[u]:returnTrue# Node is already visitedifvisited[u]:returnFalsevisited[u]=TruerecStack[u]=True# Visit all adjacent nodesforvinadj[u]:ifdfs(adj,v,visited,recStack):returnTrue# Remove node from current DFS pathrecStack[u]=FalsereturnFalsedefisCyclic(V,edges):adj=[[]for_inrange(V)]# Create adjacency listforedgeinedges:adj[edge[0]].append(edge[1])visited=[False]*VrecStack=[False]*V# Check all componentsforiinrange(V):ifnotvisited[i]anddfs(adj,i,visited,recStack):returnTruereturnFalseif__name__=="__main__":V=4edges=[[0,1],[1,2],[2,0],[2,3]]print("true"ifisCyclic(V,edges)else"false")
C#
usingSystem;usingSystem.Collections.Generic;classGFG{publicstaticbooldfs(List<List<int>>adj,intu,bool[]visited,bool[]recStack){// Node is already in the current DFS pathif(recStack[u])returntrue;// Node is already visitedif(visited[u])returnfalse;visited[u]=true;recStack[u]=true;// Visit all adjacent nodesforeach(intvinadj[u]){if(dfs(adj,v,visited,recStack))returntrue;}// Remove node from current DFS pathrecStack[u]=false;returnfalse;}publicstaticboolisCyclic(intV,int[,]edges){List<List<int>>adj=newList<List<int>>();for(inti=0;i<V;i++)adj.Add(newList<int>());// Create adjacency listfor(inti=0;i<edges.GetLength(0);i++){adj[edges[i,0]].Add(edges[i,1]);}bool[]visited=newbool[V];bool[]recStack=newbool[V];// Check all componentsfor(inti=0;i<V;i++){if(!visited[i]&&dfs(adj,i,visited,recStack))returntrue;}returnfalse;}publicstaticvoidMain(){intV=4;int[,]edges={{0,1},{1,2},{2,0},{2,3}};Console.WriteLine(isCyclic(V,edges)?"true":"false");}}
JavaScript
functiondfs(adj,u,visited,recStack){// Node is already in the current DFS pathif(recStack[u])returntrue;// Node is already visitedif(visited[u])returnfalse;visited[u]=true;recStack[u]=true;// Visit all adjacent nodesfor(letvofadj[u]){if(dfs(adj,v,visited,recStack))returntrue;}// Remove node from current DFS pathrecStack[u]=false;returnfalse;}functionisCyclic(V,edges){letadj=Array.from({length:V},()=>[]);// Create adjacency listfor(letedgeofedges){adj[edge[0]].push(edge[1]);}letvisited=newArray(V).fill(false);letrecStack=newArray(V).fill(false);// Check all componentsfor(leti=0;i<V;i++){if(!visited[i]&&dfs(adj,i,visited,recStack))returntrue;}returnfalse;}// Driver codeletV=4;letedges=[[0,1],[1,2],[2,0],[2,3]];console.log(isCyclic(V,edges)?"true":"false");
Output
true
Topological Sorting - O(V + E) Time and O(V) Space
all vertices were processed successfully. Therefore, the graph does not contain a cycle.
Output:false
C++
#includeusingnamespacestd;boolisCyclic(intV,vector<vector<int>>&edges){vector<vector<int>>adj(V);// Create adjacency listfor(auto&edge:edges){adj[edge[0]].push_back(edge[1]);}// Array to store in-degree of each vertexvector<int>inDegree(V,0);queue<int>q;// Count of visited (processed) nodesintvisited=0;// Compute in-degrees of all verticesfor(intu=0;u<V;u++){for(intv:adj[u]){inDegree[v]++;}}// Add all vertices with in-degree 0 to the queuefor(intu=0;u<V;u++){if(inDegree[u]==0){q.push(u);}}// Perform BFS (Topological Sort)while(!q.empty()){intu=q.front();q.pop();visited++;// Reduce in-degree of neighborsfor(intv:adj[u]){inDegree[v]--;if(inDegree[v]==0){// Add to queue when in-degree becomes 0q.push(v);}}}// If visited nodes != total nodes, a cycle existsreturnvisited!=V;}intmain(){intV=4;vector<vector<int>>edges={{0,1},{0,2},{1,2},{2,3}};cout<<(isCyclic(V,edges)?"true":"false")<<endl;return0;}
Java
importjava.util.Queue;importjava.util.LinkedList;importjava.util.ArrayList;classGFG{publicstaticbooleanisCyclic(intV,int[][]edges){ArrayList<ArrayList<Integer>>adj=newArrayList<>();for(inti=0;i<V;i++){adj.add(newArrayList<>());}// Create adjacency listfor(int[]edge:edges){adj.get(edge[0]).add(edge[1]);}// Array to store in-degree of each vertexint[]inDegree=newint[V];Queue<Integer>q=newLinkedList<>();// Count of visited (processed) nodesintvisited=0;// Compute in-degrees of all verticesfor(intu=0;u<V;u++){for(intv:adj.get(u)){inDegree[v]++;}}// Add all vertices with in-degree 0 to the queuefor(intu=0;u<V;u++){if(inDegree[u]==0){q.add(u);}}// Perform BFS (Topological Sort)while(!q.isEmpty()){intu=q.poll();visited++;// Reduce in-degree of neighborsfor(intv:adj.get(u)){inDegree[v]--;if(inDegree[v]==0){// Add to queue when in-degree becomes 0q.add(v);}}}// If visited nodes != total nodes, a cycle existsreturnvisited!=V;}publicstaticvoidmain(String[]args){intV=4;int[][]edges={{0,1},{0,2},{1,2},{2,3}};System.out.println(isCyclic(V,edges)?"true":"false");}}
Python
fromcollectionsimportdequedefisCyclic(V,edges):adj=[[]for_inrange(V)]# Create adjacency listforedgeinedges:adj[edge[0]].append(edge[1])# Array to store in-degree of each vertexinDegree=[0]*Vq=deque()# Count of visited (processed) nodesvisited=0# Compute in-degrees of all verticesforuinrange(V):forvinadj[u]:inDegree[v]+=1# Add all vertices with in-degree 0 to the queueforuinrange(V):ifinDegree[u]==0:q.append(u)# Perform BFS (Topological Sort)whileq:u=q.popleft()visited+=1# Reduce in-degree of neighborsforvinadj[u]:inDegree[v]-=1ifinDegree[v]==0:# Add to queue when in-degree becomes 0q.append(v)# If visited nodes != total nodes, a cycle existsreturnvisited!=Vif__name__=="__main__":V=4edges=[[0,1],[0,2],[1,2],[2,3]]print("true"ifisCyclic(V,edges)else"false")
C#
usingSystem;usingSystem.Collections.Generic;classGFG{staticboolisCyclic(intV,int[,]edges){List<List<int>>adj=newList<List<int>>();for(inti=0;i<V;i++){adj.Add(newList<int>());}// Create adjacency listfor(inti=0;i<edges.GetLength(0);i++){adj[edges[i,0]].Add(edges[i,1]);}// Array to store in-degree of each vertexint[]inDegree=newint[V];Queue<int>q=newQueue<int>();// Count of visited (processed) nodesintvisited=0;// Compute in-degrees of all verticesfor(intu=0;u<V;u++){foreach(intvinadj[u]){inDegree[v]++;}}// Add all vertices with in-degree 0 to the queuefor(intu=0;u<V;u++){if(inDegree[u]==0){q.Enqueue(u);}}// Perform BFS (Topological Sort)while(q.Count>0){intu=q.Dequeue();visited++;// Reduce in-degree of neighborsforeach(intvinadj[u]){inDegree[v]--;if(inDegree[v]==0){// Add to queue when in-degree becomes 0q.Enqueue(v);}}}// If visited nodes != total nodes, a cycle existsreturnvisited!=V;}publicstaticvoidMain(){intV=4;int[,]edges={{0,1},{0,2},{1,2},{2,3}};Console.WriteLine(isCyclic(V,edges)?"true":"false");}}
JavaScript
functionisCyclic(V,edges){letadj=Array.from({length:V},()=>[]);// Create adjacency listfor(letedgeofedges){adj[edge[0]].push(edge[1]);}// Array to store in-degree of each vertexletinDegree=newArray(V).fill(0);letq=[];// Count of visited (processed) nodesletvisited=0;// Compute in-degrees of all verticesfor(letu=0;u<V;u++){for(letvofadj[u]){inDegree[v]++;}}// Add all vertices with in-degree 0 to the queuefor(letu=0;u<V;u++){if(inDegree[u]==0){q.push(u);}}// Perform BFS (Topological Sort)letfront=0;while(front<q.length){letu=q[front++];visited++;// Reduce in-degree of neighborsfor(letvofadj[u]){inDegree[v]--;if(inDegree[v]==0){// Add to queue when in-degree becomes 0q.push(v);}}}// If visited nodes != total nodes, a cycle existsreturnvisited!=V;}// Driver codeletV=4;letedges=[[0,1],[0,2],[1,2],[2,3]];console.log(isCyclic(V,edges)?"true":"false");