src/work/marci/bfs_dfs_misc.h
author athos
Mon, 10 May 2004 16:52:51 +0000
changeset 601 6c6c0eb89b47
parent 552 83c22ca968d8
child 602 580b329c2a0c
permissions -rw-r--r--
That's what I wanted.
marci@455
     1
// -*- c++ -*-
marci@543
     2
#ifndef HUGO_BFS_DFS_MISC_H
marci@543
     3
#define HUGO_BFS_DFS_MISC_H
marci@455
     4
marci@455
     5
#include <bfs_iterator.h>
marci@455
     6
#include <for_each_macros.h>
marci@455
     7
marci@455
     8
namespace hugo {
marci@455
     9
marci@455
    10
  /// This function eat a read-write \c BoolMap& bool_map, 
marci@455
    11
  /// which have to work well up 
marci@455
    12
  /// to its \c set and \c operator[]() method. Thus we have to deal 
marci@455
    13
  /// very carefully with an uninitialized \c IterableBoolMap.
marci@455
    14
  template<typename Graph, typename BoolMap> 
marci@455
    15
  bool isBipartite(const Graph& g, BoolMap& bool_map) {
marci@455
    16
    typedef typename Graph::template NodeMap<bool> ReachedMap;
marci@455
    17
    ReachedMap reached(g/*, false*/);
marci@455
    18
    BfsIterator<Graph, ReachedMap> bfs(g, reached);
marci@455
    19
    FOR_EACH_LOC(typename Graph::NodeIt, n, g) {
marci@455
    20
      if (!reached[n]) {
marci@455
    21
	bfs.pushAndSetReached(n);
marci@549
    22
	bool_map.set(n, false);
marci@549
    23
	while (!bfs.finished()) {
marci@549
    24
	  if (bfs.isBNodeNewlyReached()) {
marci@549
    25
	    bool_map.set(bfs.bNode())=!bfs.aNode();
marci@549
    26
	  } else {
marci@549
    27
	    if (bool_map[bfs.bNode()]==bool_map[bfs.aNode()]) {
marci@549
    28
	      return false;
marci@455
    29
	    }
marci@455
    30
	  }
marci@549
    31
	  ++bfs;
marci@455
    32
	}
marci@455
    33
      }
marci@455
    34
    }
marci@549
    35
    
marci@455
    36
    return true;
marci@455
    37
  }
marci@540
    38
marci@540
    39
  /// experimental topsort, 
marci@540
    40
  /// I think the final version will work as an iterator
marci@549
    41
  /// if the graph is not a acyclic, the na pre-topological order is obtained 
marci@577
    42
  /// (see Schrijver's book).
marci@577
    43
  /// PredMap have to be a writtable node-map.
marci@577
    44
  /// If the graph is directed and not acyclic, 
marci@577
    45
  /// then going back from the returned node via the pred information, a 
marci@577
    46
  /// cycle is obtained.
marci@577
    47
  template<typename Graph, typename PredMap> 
marci@577
    48
  typename Graph::Node 
marci@577
    49
  topSort(const Graph& g, std::list<typename Graph::Node>& l, 
marci@577
    50
	       PredMap& pred) {
marci@540
    51
    l.clear();
marci@540
    52
    typedef typename Graph::template NodeMap<bool> ReachedMap;
marci@577
    53
    typedef typename Graph::template NodeMap<bool> ExaminedMap;    
marci@540
    54
    ReachedMap reached(g/*, false*/);
marci@577
    55
    ExaminedMap examined(g/*, false*/);
marci@540
    56
    DfsIterator<Graph, ReachedMap> dfs(g, reached);
marci@540
    57
    FOR_EACH_LOC(typename Graph::NodeIt, n, g) {
marci@540
    58
      if (!reached[n]) {
marci@540
    59
	dfs.pushAndSetReached(n);
marci@577
    60
	pred.set(n, INVALID);
marci@543
    61
	while (!dfs.finished()) {
marci@552
    62
	  ++dfs;
marci@577
    63
	  if (dfs.isBNodeNewlyReached()) {
marci@577
    64
	    ///\bug hugo 0.2-ben Edge kell
marci@577
    65
	    pred.set(dfs.aNode(), typename Graph::OutEdgeIt(dfs));
marci@577
    66
	  } else {
marci@577
    67
	    ///\bug ugyanaz
marci@577
    68
	    if (g.valid(typename Graph::OutEdgeIt(dfs)) && 
marci@577
    69
		!examined[dfs.bNode()]) {
marci@577
    70
	      ///\bug hugo 0.2-ben Edge kell
marci@577
    71
	      pred.set(dfs.bNode(), typename Graph::OutEdgeIt(dfs));
marci@577
    72
	      return dfs.aNode();
marci@577
    73
	    }
marci@577
    74
	  }
marci@543
    75
	  if (dfs.isANodeExamined()) {
marci@543
    76
	    l.push_back(dfs.aNode());
marci@577
    77
	    examined.set(dfs.aNode(), true);
marci@540
    78
	  }
marci@540
    79
	}
marci@540
    80
      }
marci@540
    81
    }
marci@577
    82
    return INVALID;
marci@540
    83
  }
marci@548
    84
} //namespace hugo
marci@548
    85
marci@543
    86
#endif //HUGO_BFS_DFS_MISC_H