The problem can be solved using flow networks. See the Edmonds-Karp algorithm: it involves computing augmenting paths at each step.
Find an augmenting path, like described in the Edmonds-Karp algorithm, using a breadth first search (if your graph is weighted, use Bellman-Ford).
Then, find another augmenting path in the same way. Eliminate the edges that appear in both paths (the flow algorithm will actually take care of this for you), and that will be your cycle. Basically, if you set all your edges to capacity 1
, your cycle will consist of the edges you've pushed 1
flow over.
If you don't like the flow-based solution, here's another. It's basically the same thing, just not in terms of flow algorithms.
Find a shortest path n1 -> n2
with any algorithm that can do this (Dijkstra if no negative costs, Bellman-Ford otherwise);
Replace the edges of this shortest path with directed arcs directed from n2
towards n1
. For example, if your shortest path is n1 -> x -> y -> z -> n2
, replace the edge (n1, x)
with the directed arc x -> n1
, (x, y)
with the directed arc y -> x
etc.
Also negate the costs of these arcs. For example, if (x, y)
had cost c
, the directed arc y -> x
will have cost -c
.
Find a shortest path from n1
to n2
in this new graph. You'll have to use an algorithm that works with negative edges now.
Remove the edges that appear in both of the shortest paths. What you're left with is the cycle you're after.