In: Computer Science
You are given a directed graph G(V,E) with n vertices and m edges. Let S be the subset of vertices in G that are able to reach some cycle in G. Design an O(n + m) time algorithm to compute the set S. You can assume that G is given to you in the adjacency-list representation.
import
java.util.*;
class
DirectedGraph { // A Java Program to
detect cycle in a graph
private
final
int
V;
private
final
List<List<Integer>>
adj;
public
Graph(
int
V)
{
this
.V
= V;
adj
=
new
ArrayList<>(V);
for
(
int
i =
0
; i < V; i++)
adj.add(
new
LinkedList<>());
}
// This function is a
variation of DFSUtil()
private
boolean
isCyclicUtil(
int
i,
boolean
[] visited,boolean[]
recStack)
{
//
Mark the current node as visited and
//
part of recursion stack
if
(recStack[i])
return
true
;
if
(visited[i])
return
false
;
visited[i]
=
true
;
recStack[i]
=
true
;
List<Integer>
children = adj.get(i);
for
(Integer c: children)
if
(isCyclicUtil(c, visited, recStack))
return
true
;
recStack[i]
=
false;
return
false
;
}
private
void
addEdge(
int
source,
int
dest) {
adj.get(source).add(dest);
}
// Returns true if
the graph contains a
// cycle, else
false.
// This function is a
variation of DFS()
private
boolean
isCyclic() //
Time Complexity of
this method is same as time complexity of DFS traversal which is
O(V+E).
{
//
Mark all the vertices as not visited and
//
not part of recursion stack
boolean
[]
visited =
new
boolean
[V];
boolean
[]
recStack =
new
boolean
[V];
//
Call the recursive helper function to
//
detect cycle in different DFS trees
for
(
int
i =
0
; i < V; i++)
if
(isCyclicUtil(i, visited, recStack))
return
true
;
return
false
;
}
// Driver
code
public
static
void
main(String[]
args)
{
Graph
graph =
new
Graph(
4
);
graph.addEdge(
0
,
1
);
graph.addEdge(
0
,
2
);
graph.addEdge(
1
,
2
);
graph.addEdge(
2
,
0
);
graph.addEdge(
2
,
3
);
graph.addEdge(
3
,
3
);
if
(graph.isCyclic())
System.out.println(
"Graph
contains cycle"
);
else
System.out.println(
"Graph
doesn't "+ "contain cycle"
);
}
}
}