The problem is: given a directed graph, find the longest simple cycle in the graph. I've searched the question and found this link Finding the longest cycle in a directed graph using DFS. The answer explains this is an NP hard problem.
But I'm confused by the following algorithm, it seems to run in O(|V| + |E|) time because we visit each edge exactly once.
maintain the following variables:
(1) global max
: the length of the longest cycle in the graph.
(2) Map<GraphNode, Integer> cache
: stores length of the longest cycle starting from the key node.
(3) Map<GraphNode, Integer> pathVisited
: stores the node visited on the path and the corresponding step number. For example, A -> B -> C -> A, if starts from A, the Map will look like {A -> 1, B -> 2, C -> 3}, and when enters A again, the step becomes 4, and thus the length of cycle is 4 - 1 = 3
(4)Set<GraphNode> visited
: contains the graphNodes that have been fully explored.
dfs(GraphNode cur, int curStep, Set<GraphNode> visited, Map<GraphNode, Integer> cache, Map<GraphNode, Integer> pathVisited):
if visited.containsKey(cur), then
return // if the node have been explored, no need to explore again
// if see a cycle, update the results(cache)
if pathVisited.containsKey(cur), then
newCycleLen = curStep - pathVisited.get(cur)
cache.put(cur, max {newCycleLen, cache.get(cur)})
return
// no cycle yet, continue the search
pathVisited.put(cur, curStep)
for each neighbor of cur:
dfs(neighbor, curStep + 1, cache, pathVisited)
endfor
visited.add(cur); // current node have been explored, in the future no need to visit it again.
path.remove(cur)
I feel the above algorithm can solve the problem in O(|V| + |E|) time, because after fully exploring one node, we won't start dfs on that node again.
Can anyone give me some hint on why the above algorithm is wrong?
Consider the following graph:
D -- A
/ | |
E | |
\ | |
C -- B
Now, imagine you start your DFS at node A and visit the nodes in the order B, then C, then D, and then E. Unless I've misinterpreted what your code is doing, I don't believe that this visitation order will allow you to discover the longest cycle A, B, C, E, D, A, since once you've visited D you've assigned it the wrong depth and cut off the path back to A.