Given a directed graph G N nodes and E Edges consisting of nodes valued [0, N – 1] and a 2D array Edges[][2] of type {u, v} that denotes a directed edge between vertices u and v. The task is to find the nodes that are not part of any cycle in the given graph G.
Examples:
Input: N = 4, E = 4, Edges[][2] = { {0, 2}, {0, 1}, {2, 3}, {3, 0} }
Output: 1
Explanation:

From the given graph above there exists a cycle between the nodes 0 -> 2 -> 3 -> 0.
Node which doesn’t occurs in any cycle is 1.
Hence, print 1.
Input: N = 6, E = 7, Edges[][2] = { {0, 1}, {0, 2}, {1, 3}, {2, 1}, {2, 5}, {3, 0}, {4, 5}}
Output: 4 5
Explanation:

From the given graph above there exists a cycle between the nodes:
1) 0 -> 1 -> 3 -> 0.
2) 0 -> 2 -> 1 -> 3 -> 0.
Nodes which doesn’t occurs in any cycle are 4 and 5.
Hence, print 4 and 5.
Naive Approach: The simplest approach is to detect a cycle in a directed graph for each node in the given graph and print only those nodes that are not a part of any cycle in the given graph.
Time Complexity: O(V * (V + E)), where V is the number of vertices and E is the number of edges.
Auxiliary Space: O(V)
Efficient Approach: To optimize the above approach, the idea is to store the intermediate node as a visited cycle node whenever any cycle in the given graph. To implement this part use an auxiliary array cyclePart[] that will store the intermediate cycle node while performing the DFS Traversal. Below are the steps:
- Initialize an auxiliary array cyclePart[] of size N, such that if cyclePart[i] = 0, then ith node doesn’t exist in any cycle.
- Initialize an auxiliary array recStack[] of size N, such that it will store the visited node in the recursion stack by marking that node as true.
- Perform the DFS Traversal on the given graph for each unvisited node and do the following:
- Now find a cycle in the given graph, whenever a cycle is found, mark the node in cyclePart[] as true as this node is a part of the cycle.
- If any node is visited in the recursive call and is recStack[node] is also true then that node is a part of the cycle then mark that node as true.
- After performing the DFS Traversal, traverse the array cyclePart[] and print all those nodes that are marked as false as these nodes are not the part of any cycle.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Graph {
int V;
list< int >* adj;
bool printNodesNotInCycleUtil(
int v, bool visited[], bool * rs,
bool * cyclePart);
public :
Graph( int V);
void addEdge( int v, int w);
void printNodesNotInCycle();
};
Graph::Graph( int V)
{
this ->V = V;
adj = new list< int >[V];
}
void Graph::addEdge( int v, int w)
{
adj[v].push_back(w);
}
bool Graph::printNodesNotInCycleUtil(
int v, bool visited[],
bool * recStack, bool * cyclePart)
{
if (visited[v] == false ) {
visited[v] = true ;
recStack[v] = true ;
for ( auto & child : adj[v]) {
if (!visited[child]
&& printNodesNotInCycleUtil(
child, visited,
recStack, cyclePart)) {
cyclePart[child] = 1;
return true ;
}
else if (recStack[child]) {
cyclePart[child] = 1;
return true ;
}
}
}
recStack[v] = false ;
return false ;
}
void Graph::printNodesNotInCycle()
{
bool * visited = new bool [V];
bool * recStack = new bool [V];
bool * cyclePart = new bool [V];
for ( int i = 0; i < V; i++) {
visited[i] = false ;
recStack[i] = false ;
cyclePart[i] = false ;
}
for ( int i = 0; i < V; i++) {
if (!visited[i]) {
if (printNodesNotInCycleUtil(
i, visited, recStack,
cyclePart)) {
cyclePart[i] = 1;
}
}
}
for ( int i = 0; i < V; i++) {
if (cyclePart[i] == 0) {
cout << i << " " ;
}
}
}
void solve( int N, int E,
int Edges[][2])
{
Graph g(N);
for ( int i = 0; i < E; i++) {
g.addEdge(Edges[i][0],
Edges[i][1]);
}
g.printNodesNotInCycle();
}
int main()
{
int N = 6;
int E = 7;
int Edges[][2] = { { 0, 1 }, { 0, 2 },
{ 1, 3 }, { 2, 1 },
{ 2, 5 }, { 3, 0 },
{ 4, 5 } };
solve(N, E, Edges);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
class GFG
{
static ArrayList<ArrayList<Integer>> adj;
static int V;
static boolean printNodesNotInCycleUtil(
int v, boolean visited[],
boolean [] recStack, boolean [] cyclePart)
{
if (visited[v] == false )
{
visited[v] = true ;
recStack[v] = true ;
for (Integer child : adj.get(v))
{
if (!visited[child]
&& printNodesNotInCycleUtil(
child, visited,
recStack, cyclePart))
{
cyclePart[child] = true ;
return true ;
}
else if (recStack[child])
{
cyclePart[child] = true ;
return true ;
}
}
}
recStack[v] = false ;
return false ;
}
static void printNodesNotInCycle()
{
boolean [] visited = new boolean [V];
boolean [] recStack = new boolean [V];
boolean [] cyclePart = new boolean [V];
for ( int i = 0 ; i < V; i++)
{
if (!visited[i])
{
if (printNodesNotInCycleUtil(
i, visited, recStack,
cyclePart)) {
cyclePart[i] = true ;
}
}
}
for ( int i = 0 ; i < V; i++)
{
if (!cyclePart[i])
{
System.out.print(i+ " " );
}
}
}
static void solve( int N, int E,
int Edges[][])
{
adj = new ArrayList<>();
for ( int i = 0 ; i < N; i++)
adj.add( new ArrayList<>());
for ( int i = 0 ; i < E; i++)
{
adj.get(Edges[i][ 0 ]).add(Edges[i][ 1 ]);
}
printNodesNotInCycle();
}
public static void main (String[] args)
{
V = 6 ;
int E = 7 ;
int Edges[][] = { { 0 , 1 }, { 0 , 2 },
{ 1 , 3 }, { 2 , 1 },
{ 2 , 5 }, { 3 , 0 },
{ 4 , 5 } };
solve(V, E, Edges);
}
}
|
Python3
class Graph:
def __init__( self , V):
self .V = V
self .adj = [[] for i in range ( self .V)]
def addEdge( self , v, w):
self .adj[v].append(w);
def printNodesNotInCycleUtil( self , v, visited,recStack, cyclePart):
if (visited[v] = = False ):
visited[v] = True ;
recStack[v] = True ;
for child in self .adj[v]:
if ( not visited[child] and self .printNodesNotInCycleUtil(child, visited,recStack, cyclePart)):
cyclePart[child] = 1 ;
return True ;
elif (recStack[child]):
cyclePart[child] = 1 ;
return True ;
recStack[v] = False ;
return False ;
def printNodesNotInCycle( self ):
visited = [ False for i in range ( self .V)];
recStack = [ False for i in range ( self .V)];
cyclePart = [ False for i in range ( self .V)]
for i in range ( self .V):
if ( not visited[i]):
if ( self .printNodesNotInCycleUtil(
i, visited, recStack,
cyclePart)):
cyclePart[i] = 1 ;
for i in range ( self .V):
if (cyclePart[i] = = 0 ) :
print (i,end = ' ' )
def solve( N, E, Edges):
g = Graph(N);
for i in range (E):
g.addEdge(Edges[i][ 0 ],
Edges[i][ 1 ]);
g.printNodesNotInCycle();
if __name__ = = '__main__' :
N = 6 ;
E = 7 ;
Edges = [ [ 0 , 1 ], [ 0 , 2 ],
[ 1 , 3 ], [ 2 , 1 ],
[ 2 , 5 ], [ 3 , 0 ],
[ 4 , 5 ] ];
solve(N, E, Edges);
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static List<List< int >> adj;
static int V;
static bool printNodesNotInCycleUtil(
int v, bool []visited,
bool [] recStack, bool [] cyclePart)
{
if (visited[v] == false )
{
visited[v] = true ;
recStack[v] = true ;
foreach ( int child in adj[v])
{
if (!visited[child]
&& printNodesNotInCycleUtil(
child, visited,
recStack, cyclePart))
{
cyclePart[child] = true ;
return true ;
}
else if (recStack[child])
{
cyclePart[child] = true ;
return true ;
}
}
}
recStack[v] = false ;
return false ;
}
static void printNodesNotInCycle()
{
bool [] visited = new bool [V];
bool [] recStack = new bool [V];
bool [] cyclePart = new bool [V];
for ( int i = 0; i < V; i++)
{
if (!visited[i])
{
if (printNodesNotInCycleUtil(
i, visited, recStack,
cyclePart)) {
cyclePart[i] = true ;
}
}
}
for ( int i = 0; i < V; i++)
{
if (!cyclePart[i])
{
Console.Write(i+ " " );
}
}
}
static void solve( int N, int E,
int [,]Edges)
{
adj = new List<List< int >>();
for ( int i = 0; i < N; i++)
adj.Add( new List< int >());
for ( int i = 0; i < E; i++)
{
adj[Edges[i,0]].Add(Edges[i,1]);
}
printNodesNotInCycle();
}
public static void Main(String[] args)
{
V = 6;
int E = 7;
int [,]Edges = { { 0, 1 }, { 0, 2 },
{ 1, 3 }, { 2, 1 },
{ 2, 5 }, { 3, 0 },
{ 4, 5 } };
solve(V, E, Edges);
}
}
|
Javascript
<script>
class Graph{
constructor(V){
this .V = V
this .adj = new Array(V).fill(0).map(()=>[])
}
addEdge(v, w){
this .adj[v].push(w);
}
printNodesNotInCycleUtil(v, visited,recStack, cyclePart){
if (visited[v] == false ){
visited[v] = true ;
recStack[v] = true ;
for (let child of this .adj[v]){
if (visited[child] == false && this .printNodesNotInCycleUtil(child, visited,recStack, cyclePart)){
cyclePart[child] = 1;
return true ;
}
else if (recStack[child]){
cyclePart[child] = 1;
return true ;
}
}
}
recStack[v] = false ;
return false ;
}
printNodesNotInCycle(){
let visited = new Array( this .V).fill( false );
let recStack = new Array( this .V).fill( false );
let cyclePart = new Array( this .V).fill( false )
for (let i=0;i< this .V;i++){
if (visited[i] == false ){
if ( this .printNodesNotInCycleUtil(
i, visited, recStack,
cyclePart))
cyclePart[i] = 1;
}
}
for (let i=0;i< this .V;i++){
if (cyclePart[i] == 0)
document.write(i, ' ' )
}
}
}
function solve(N, E, Edges){
let g = new Graph(N);
for (let i=0;i<E;i++){
g.addEdge(Edges[i][0],
Edges[i][1]);
}
g.printNodesNotInCycle();
}
let N = 6;
let E = 7;
let Edges = [ [ 0, 1 ], [ 0, 2 ],
[ 1, 3 ], [ 2, 1 ],
[ 2, 5 ], [ 3, 0 ],
[ 4, 5 ] ];
solve(N, E, Edges)
</script>
|
Time Complexity: O(V + E)
Space Complexity: O(V)
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!
Last Updated :
14 Apr, 2023
Like Article
Save Article