Code Fragment: FindCycleDFS



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
  }
};