[EDIT: As noted by Kraskevich, the final step of the query may be worse than I originally stated: up to O (| V | ^ 2) even to output the size of O (| V |), which is no better than regular DFS without any preprocessing. ] .
In the worst case, the space O (| V | ^ 2) is required to store all this information explicitly, i.e. keep a complete list of reachable vertices for each vertex (think of a graph in which each vertex has an edge for each other vertex). But you can imagine it in such a way that only the space O (| V |) is required, and this representation can be built in O (| V | + | E |) time , and the request for it will only be time proportional to the size of the response ( number of reachable vertices) .
Main idea: Each vertex in a strongly connected component (SCC) can reach any other vertex in the same SCC (this is the definition of SCC) and can reach all the vertices in the SCC that it can reach and other vertices.
- Find all SCC; this can be done in O (| V | + | E |). Create an SCC table, so SCC (u) = i if SCC is from u is i (both vertices in G and SCC can be represented as integers). Then go through this table one more time to create a double Verts table, so that Verts (i) contains a list of all the vertices in the ith SCC.
- We construct a new graph G 'whose vertices are SCC G. G' will necessarily be acyclic.
So, given the vertex u in G, find its SCC, SCC (u). Call it i. Run DFS through G 'starting at vertex i: for each vertex (from G') j encountered during this DFS, output each vertex (from G) to Verts (j).
source share