template <typename Graph> class FindCycleDFS : public DFS<Graph> { protected: // local types typedef typename Graph::Vertex Vertex; typedef typename Graph::Edge Edge; // ... (other Graph typenames omitted) private: // local data bool cycleDetected; // cycle detected? Vertex cycleStart; // start of cycle EdgeSequence cycle; // cycle storage protected: // overrriden functions virtual void finishVisit(const Vertex& v) { // finished with vertex if ((!cycle.isEmpty()) && (!cycleDetected)) // not building a cycle? cycle.remove(cycle.last()); // remove this edge } virtual void traverseDiscovery(const Edge& e, const Vertex& from) { if (!cycleDetected) cycle.insertLast(e); } // add edge to sequence virtual void traverseBack(const Edge& e, const Vertex& from) { if (!cycleDetected) { // no cycle yet? cycleDetected = true; // cycle is now detected cycle.insertLast(e); // insert back edge cycleStart = G.opposite(from, e); // save starting vertex } } virtual bool isDone() const { return cycleDetected; } // done yet? public: FindCycleDFS(const Graph& g) : DFS<Graph>(g) { } // constructor EdgeSequence run(const Vertex& s) { // find a cycle from s initialize(); // initialize DFS cycle = EdgeSequence(); // create cycle sequence cycleDetected = false; dfsTraversal(s); // do the search if (!cycle.isEmpty() && s != cycleStart) { // found a cycle? EdgeSeqPosIterator pi = cycle.positions(); while (pi.hasNext()) { // remove the tail EdgeSeqPosition ep = pi.next(); cycle.remove(ep); // ...up to cycleStart if (G.areIncident(cycleStart, ep.element())) break; } } return cycle; // return the cycle } };