Detect cycle in Directed Graph using Topological Sort
Given a Directed Graph consisting of N vertices and M edges and a set of Edges[][], the task is to check whether the graph contains a cycle or not using Topological sort.
Topological sort of directed graph is a linear ordering of its vertices such that, for every directed edge U -> V from vertex U to vertex V, U comes before V in the ordering.
Examples:
Input: N = 4, M = 6, Edges[][] = {{0, 1}, {1, 2}, {2, 0}, {0, 2}, {2, 3}, {3, 3}}
Output: Yes
Explanation:
A cycle 0 -> 2 -> 0 exists in the given graph
Input: N = 4, M = 3, Edges[][] = {{0, 1}, {1, 2}, {2, 3}, {0, 2}}
Output: No
Approach:
In Topological Sort, the idea is to visit the parent node followed by the child node. If the given graph contains a cycle, then there is at least one node which is a parent as well as a child so this will break Topological Order. Therefore, after the topological sort, check for every directed edge whether it follows the order or not.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int n, m ;
stack< int > s;
vector< int > tsort;
vector< int > adj[ int (1e5) + 1];
vector< int > visited( int (1e5) + 1);
void dfs( int u)
{
visited[u] = 1;
for ( auto it : adj[u]) {
if (visited[it] == 0)
dfs(it);
}
s.push(u);
}
bool check_cycle()
{
unordered_map< int , int > pos;
int index = 0;
while (!s.empty()) {
pos[s.top()] = index;
tsort.push_back(s.top());
index += 1;
s.pop();
}
for ( int i = 0; i < n; i++) {
for ( auto it : adj[i]) {
if (pos[i] > pos[it]) {
return true ;
}
}
}
return false ;
}
void addEdge( int u, int v)
{
adj[u].push_back(v);
}
int main()
{
n = 4, m = 5;
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 2);
addEdge(2, 0);
addEdge(2, 3);
for ( int i = 0; i < n; i++) {
if (visited[i] == 0) {
dfs(i);
}
}
if (check_cycle())
cout << "Yes" ;
else
cout << "No" ;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int t, n, m, a;
static Stack<Integer> s;
static ArrayList<Integer> tsort;
static ArrayList<ArrayList<Integer>> adj;
static int [] visited = new int [( int )1e5 + 1 ];
static void dfs( int u)
{
visited[u] = 1 ;
for (Integer it : adj.get(u))
{
if (visited[it] == 0 )
dfs(it);
}
s.push(u);
}
static boolean check_cycle()
{
Map<Integer, Integer> pos = new HashMap<>();
int ind = 0 ;
while (!s.isEmpty())
{
pos.put(s.peek(), ind);
tsort.add(s.peek());
ind += 1 ;
s.pop();
}
for ( int i = 0 ; i < n; i++)
{
for (Integer it : adj.get(i))
{
if (pos.get(i) > pos.get(it))
{
return true ;
}
}
}
return false ;
}
static void addEdge( int u, int v)
{
adj.get(u).add(v);
}
public static void main (String[] args)
{
n = 4 ; m = 5 ;
s = new Stack<>();
adj = new ArrayList<>();
tsort = new ArrayList<>();
for ( int i = 0 ; i < 4 ; i++)
adj.add( new ArrayList<>());
addEdge( 0 , 1 );
addEdge( 0 , 2 );
addEdge( 1 , 2 );
addEdge( 2 , 0 );
addEdge( 2 , 3 );
for ( int i = 0 ; i < n; i++)
{
if (visited[i] == 0 )
{
dfs(i);
}
}
if (check_cycle())
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
t = 0
n = 0
m = 0
a = 0
s = []
tsort = []
adj = [[] for i in range ( 100001 )]
visited = [ False for i in range ( 100001 )]
def dfs(u):
visited[u] = 1
for it in adj[u]:
if (visited[it] = = 0 ):
dfs(it)
s.append(u)
def check_cycle():
pos = dict ()
ind = 0
while ( len (s) ! = 0 ):
pos[s[ - 1 ]] = ind
tsort.append(s[ - 1 ])
ind + = 1
s.pop()
for i in range (n):
for it in adj[i]:
first = 0 if i not in pos else pos[i]
second = 0 if it not in pos else pos[it]
if (first > second):
return True
return False
def addEdge(u, v):
adj[u].append(v)
if __name__ = = "__main__" :
n = 4
m = 5
addEdge( 0 , 1 )
addEdge( 0 , 2 )
addEdge( 1 , 2 )
addEdge( 2 , 0 )
addEdge( 2 , 3 )
for i in range (n):
if (visited[i] = = False ):
dfs(i)
if (check_cycle()):
print ( 'Yes' )
else :
print ( 'No' )
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
static int n;
static Stack< int > s;
static ArrayList tsort;
static ArrayList adj;
static int [] visited = new int [100001];
static void dfs( int u)
{
visited[u] = 1;
foreach ( int it in (ArrayList)adj[u])
{
if (visited[it] == 0)
dfs(it);
}
s.Push(u);
}
static bool check_cycle()
{
Dictionary< int ,
int > pos = new Dictionary< int ,
int >();
int ind = 0;
while (s.Count != 0)
{
pos.Add(s.Peek(), ind);
tsort.Add(s.Peek());
ind += 1;
s.Pop();
}
for ( int i = 0; i < n; i++)
{
foreach ( int it in (ArrayList)adj[i])
{
if (pos[i] > pos[it])
{
return true ;
}
}
}
return false ;
}
static void addEdge( int u, int v)
{
((ArrayList)adj[u]).Add(v);
}
public static void Main( string [] args)
{
n = 4;
s = new Stack< int >();
adj = new ArrayList();
tsort = new ArrayList();
for ( int i = 0; i < 4; i++)
adj.Add( new ArrayList());
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 2);
addEdge(2, 0);
addEdge(2, 3);
for ( int i = 0; i < n; i++)
{
if (visited[i] == 0)
{
dfs(i);
}
}
if (check_cycle())
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
}
}
|
Javascript
<script>
var t, n, m, a;
var s = [];
var tsort = [];
var adj = Array.from(Array(100001), ()=>Array());
var visited = Array(100001).fill(0);
function dfs(u)
{
visited[u] = 1;
adj[u].forEach(it => {
if (visited[it] == 0)
dfs(it);
});
s.push(u);
}
function check_cycle()
{
var pos = new Map();
var ind = 0;
while (s.length!=0) {
pos.set(s[s.length-1], ind);
tsort.push(s[s.length-1]);
ind += 1;
s.pop();
}
var ans = false ;
for ( var i = 0; i < n; i++) {
adj[i].forEach(it => {
if ((pos.has(i)?pos.get(i):0) >
(pos.has(it)?pos.get(it):0))
{
ans = true ;
}
});
};
return ans;
}
function addEdge(u, v)
{
adj[u].push(v);
}
n = 4, m = 5;
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 2);
addEdge(2, 0);
addEdge(2, 3);
for ( var i = 0; i < n; i++) {
if (visited[i] == 0) {
dfs(i);
}
}
if (check_cycle())
document.write( "Yes" );
else
document.write( "No" );
</script>
|
Time Complexity: O(N + M)
Auxiliary Space: O(N)
Last Updated :
30 Oct, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...