Asked By : J. Abraham
Answered By : D.W.
KWillets’ algorithm
KWillets seems to have the best algorithm. Basically, you iteratively alternate between the following two steps:
- For each source (vertex with no outgoing edge), remove the source and all edges leading out from it. Repeat until there are no more sources.
- Remove the highest-numbered edge, i.e., the one that is at the latest time (out of all remaining edges). Go back to step 1.
When the graph is empty, undo the last step 1 and step 2, and there’s the earliest graph with a cycle. In other words, take the last edge removed in the last step 2 before the graph becomes empty, and the graph containing that edge and all earlier edges is the first one containing a cycle. Since your list of edges is already sorted by increasing time, this can be implemented in $O(V+E)$ time. You’ll maintain the list of edges in a doubly-linked list, with pointers between those nodes and the corresponding edge in the graph. Step 1 requires $O(1)$ time per node or edge deleted, if you keep a separate worklist of all source vertices and any time you delete an edge you check whether that has created a new source vertex.
Binary search
It’s possible to make some small optimizations to your binary search method, though they won’t improve the asymptotic running time: the asymptotic running time will still be $O((V+E)log E)$. Suppose you analyze the graph at time $k$, and discover that it does contain a cycle. Decompose the graph into strongly connected components. Now you can permanently delete all isolated nodes (i.e., nodes that are in a SCC of size 1); they cannot be part of a cycle. You can continue the binary search from here. Also, when you decompose into strongly connected components, for each strongly connected component, do the following. Count the number of nodes in the SCC, say $n_0$ of them. Sort the edges within the SCC in increasing time. Look at the time of the $n_0$th of them, say time $j_0$. Then the first time when there is a cycle within that strongly connected component must be time $j_0$ or later. Do this for each strongly connected component, and take the earliest of those times. Then, as an optimization, there is no need to consider any time earlier than that during the binary search. However, these two optimizations probably won’t provide more than a small constant-factor speedup, at best.
Best Answer from StackOverflow
Question Source : http://cs.stackexchange.com/questions/65633 3.2K people like this