marci@455: // -*- c++ -*- marci@543: #ifndef HUGO_BFS_DFS_MISC_H marci@543: #define HUGO_BFS_DFS_MISC_H marci@455: marci@615: /// \ingroup galgs marci@615: /// \file marci@615: /// \brief Miscellaneous algorithms using bfs and dfs. marci@604: /// marci@615: /// This file contains several algorithms using bfs and dfs. marci@604: /// marci@604: // ///\author Marton Makai marci@604: marci@602: #include marci@455: #include marci@455: marci@455: namespace hugo { marci@455: marci@615: /// This function eats a read-write \c BoolMap& bool_map, marci@455: /// which have to work well up marci@455: /// to its \c set and \c operator[]() method. Thus we have to deal marci@455: /// very carefully with an uninitialized \c IterableBoolMap. marci@615: /// \ingroup galgs marci@455: template marci@455: bool isBipartite(const Graph& g, BoolMap& bool_map) { marci@455: typedef typename Graph::template NodeMap ReachedMap; marci@455: ReachedMap reached(g/*, false*/); marci@455: BfsIterator bfs(g, reached); marci@455: FOR_EACH_LOC(typename Graph::NodeIt, n, g) { marci@455: if (!reached[n]) { marci@455: bfs.pushAndSetReached(n); marci@549: bool_map.set(n, false); marci@549: while (!bfs.finished()) { marci@549: if (bfs.isBNodeNewlyReached()) { marci@549: bool_map.set(bfs.bNode())=!bfs.aNode(); marci@549: } else { marci@549: if (bool_map[bfs.bNode()]==bool_map[bfs.aNode()]) { marci@549: return false; marci@455: } marci@455: } marci@549: ++bfs; marci@455: } marci@455: } marci@455: } marci@549: marci@455: return true; marci@455: } marci@540: marci@540: /// experimental topsort, marci@540: /// I think the final version will work as an iterator marci@549: /// if the graph is not a acyclic, the na pre-topological order is obtained marci@577: /// (see Schrijver's book). marci@577: /// PredMap have to be a writtable node-map. marci@577: /// If the graph is directed and not acyclic, marci@577: /// then going back from the returned node via the pred information, a marci@577: /// cycle is obtained. marci@615: /// \ingroup galgs marci@577: template marci@577: typename Graph::Node marci@577: topSort(const Graph& g, std::list& l, marci@577: PredMap& pred) { marci@540: l.clear(); marci@540: typedef typename Graph::template NodeMap ReachedMap; marci@577: typedef typename Graph::template NodeMap ExaminedMap; marci@540: ReachedMap reached(g/*, false*/); marci@577: ExaminedMap examined(g/*, false*/); marci@540: DfsIterator dfs(g, reached); marci@540: FOR_EACH_LOC(typename Graph::NodeIt, n, g) { marci@540: if (!reached[n]) { marci@540: dfs.pushAndSetReached(n); marci@577: pred.set(n, INVALID); marci@543: while (!dfs.finished()) { marci@552: ++dfs; marci@577: if (dfs.isBNodeNewlyReached()) { marci@577: ///\bug hugo 0.2-ben Edge kell marci@577: pred.set(dfs.aNode(), typename Graph::OutEdgeIt(dfs)); marci@577: } else { marci@577: ///\bug ugyanaz marci@577: if (g.valid(typename Graph::OutEdgeIt(dfs)) && marci@577: !examined[dfs.bNode()]) { marci@577: ///\bug hugo 0.2-ben Edge kell marci@577: pred.set(dfs.bNode(), typename Graph::OutEdgeIt(dfs)); marci@577: return dfs.aNode(); marci@577: } marci@577: } marci@543: if (dfs.isANodeExamined()) { marci@543: l.push_back(dfs.aNode()); marci@577: examined.set(dfs.aNode(), true); marci@540: } marci@540: } marci@540: } marci@540: } marci@577: return INVALID; marci@540: } marci@615: marci@548: } //namespace hugo marci@548: marci@543: #endif //HUGO_BFS_DFS_MISC_H