lemon/topology.h
author convert-repo
Thu, 04 Mar 2010 19:34:55 +0000
changeset 2659 611ced85018b
parent 2529 93de38566e6c
permissions -rw-r--r--
update tags
deba@1698
     1
/* -*- C++ -*-
deba@1698
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1698
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1698
     8
 *
deba@1698
     9
 * Permission to use, modify and distribute this software is granted
deba@1698
    10
 * provided that this copyright notice appears in all copies. For
deba@1698
    11
 * precise terms see the accompanying LICENSE file.
deba@1698
    12
 *
deba@1698
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1698
    14
 * express or implied, and with no claim as to its suitability for any
deba@1698
    15
 * purpose.
deba@1698
    16
 *
deba@1698
    17
 */
deba@1698
    18
deba@1698
    19
#ifndef LEMON_TOPOLOGY_H
deba@1698
    20
#define LEMON_TOPOLOGY_H
deba@1698
    21
deba@1698
    22
#include <lemon/dfs.h>
deba@1740
    23
#include <lemon/bfs.h>
deba@1698
    24
#include <lemon/graph_utils.h>
deba@1750
    25
#include <lemon/graph_adaptor.h>
deba@1750
    26
#include <lemon/maps.h>
deba@1698
    27
alpar@2260
    28
#include <lemon/concepts/graph.h>
alpar@2260
    29
#include <lemon/concepts/ugraph.h>
deba@1698
    30
#include <lemon/concept_check.h>
deba@1698
    31
deba@1750
    32
#include <lemon/bin_heap.h>
deba@2038
    33
#include <lemon/bucket_heap.h>
deba@1750
    34
deba@1750
    35
#include <stack>
deba@1750
    36
#include <functional>
deba@1750
    37
deba@2429
    38
/// \ingroup graph_prop
deba@1698
    39
/// \file
deba@1698
    40
/// \brief Topology related algorithms
deba@1698
    41
///
deba@1698
    42
/// Topology related algorithms
deba@1698
    43
deba@1698
    44
namespace lemon {
deba@1698
    45
deba@2429
    46
  /// \ingroup graph_prop
deba@1750
    47
  ///
deba@1750
    48
  /// \brief Check that the given undirected graph is connected.
deba@1750
    49
  ///
deba@1750
    50
  /// Check that the given undirected graph connected.
deba@1750
    51
  /// \param graph The undirected graph.
deba@1750
    52
  /// \return %True when there is path between any two nodes in the graph.
alpar@1807
    53
  /// \note By definition, the empty graph is connected.
klao@1909
    54
  template <typename UGraph>
klao@1909
    55
  bool connected(const UGraph& graph) {
alpar@2260
    56
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
    57
    typedef typename UGraph::NodeIt NodeIt;
alpar@1807
    58
    if (NodeIt(graph) == INVALID) return true;
klao@1909
    59
    Dfs<UGraph> dfs(graph);
deba@1750
    60
    dfs.run(NodeIt(graph));
deba@1750
    61
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
    62
      if (!dfs.reached(it)) {
deba@1750
    63
	return false;
deba@1750
    64
      }
deba@1750
    65
    }
deba@1750
    66
    return true;
deba@1750
    67
  }
deba@1750
    68
deba@2429
    69
  /// \ingroup graph_prop
deba@1750
    70
  ///
deba@1750
    71
  /// \brief Count the number of connected components of an undirected graph
deba@1750
    72
  ///
deba@1750
    73
  /// Count the number of connected components of an undirected graph
deba@1750
    74
  ///
deba@1793
    75
  /// \param graph The graph. It should be undirected.
deba@1750
    76
  /// \return The number of components
alpar@1807
    77
  /// \note By definition, the empty graph consists
alpar@1807
    78
  /// of zero connected components.
klao@1909
    79
  template <typename UGraph>
klao@1909
    80
  int countConnectedComponents(const UGraph &graph) {
alpar@2260
    81
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
    82
    typedef typename UGraph::Node Node;
klao@1909
    83
    typedef typename UGraph::Edge Edge;
deba@1750
    84
deba@1750
    85
    typedef NullMap<Node, Edge> PredMap;
deba@1750
    86
    typedef NullMap<Node, int> DistMap;
deba@1750
    87
deba@1750
    88
    int compNum = 0;
klao@1909
    89
    typename Bfs<UGraph>::
deba@1750
    90
      template DefPredMap<PredMap>::
deba@1750
    91
      template DefDistMap<DistMap>::
deba@1750
    92
      Create bfs(graph);
deba@1750
    93
deba@1750
    94
    PredMap predMap;
deba@1750
    95
    bfs.predMap(predMap);
deba@1750
    96
deba@1750
    97
    DistMap distMap;
deba@1750
    98
    bfs.distMap(distMap);
deba@1750
    99
deba@1750
   100
    bfs.init();
klao@1909
   101
    for(typename UGraph::NodeIt n(graph); n != INVALID; ++n) {
deba@1750
   102
      if (!bfs.reached(n)) {
deba@1750
   103
	bfs.addSource(n);
deba@1750
   104
	bfs.start();
deba@1750
   105
	++compNum;
deba@1750
   106
      }
deba@1750
   107
    }
deba@1750
   108
    return compNum;
deba@1750
   109
  }
deba@1750
   110
deba@2429
   111
  /// \ingroup graph_prop
deba@1750
   112
  ///
deba@1750
   113
  /// \brief Find the connected components of an undirected graph
deba@1750
   114
  ///
deba@1750
   115
  /// Find the connected components of an undirected graph.
deba@1750
   116
  ///
deba@1763
   117
  /// \image html connected_components.png
deba@1763
   118
  /// \image latex connected_components.eps "Connected components" width=\textwidth
deba@1763
   119
  ///
deba@1793
   120
  /// \param graph The graph. It should be undirected.
deba@1793
   121
  /// \retval compMap A writable node map. The values will be set from 0 to
deba@1750
   122
  /// the number of the connected components minus one. Each values of the map
deba@1750
   123
  /// will be set exactly once, the values of a certain component will be
deba@1750
   124
  /// set continuously.
deba@1750
   125
  /// \return The number of components
deba@1763
   126
  ///
klao@1909
   127
  template <class UGraph, class NodeMap>
klao@1909
   128
  int connectedComponents(const UGraph &graph, NodeMap &compMap) {
alpar@2260
   129
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
   130
    typedef typename UGraph::Node Node;
klao@1909
   131
    typedef typename UGraph::Edge Edge;
alpar@2260
   132
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
deba@1750
   133
deba@1750
   134
    typedef NullMap<Node, Edge> PredMap;
deba@1750
   135
    typedef NullMap<Node, int> DistMap;
deba@1750
   136
deba@1750
   137
    int compNum = 0;
klao@1909
   138
    typename Bfs<UGraph>::
deba@1750
   139
      template DefPredMap<PredMap>::
deba@1750
   140
      template DefDistMap<DistMap>::
deba@1750
   141
      Create bfs(graph);
deba@1750
   142
deba@1750
   143
    PredMap predMap;
deba@1750
   144
    bfs.predMap(predMap);
deba@1750
   145
deba@1750
   146
    DistMap distMap;
deba@1750
   147
    bfs.distMap(distMap);
deba@1750
   148
    
deba@1750
   149
    bfs.init();
klao@1909
   150
    for(typename UGraph::NodeIt n(graph); n != INVALID; ++n) {
deba@1750
   151
      if(!bfs.reached(n)) {
deba@1750
   152
	bfs.addSource(n);
deba@1750
   153
	while (!bfs.emptyQueue()) {
deba@1750
   154
	  compMap.set(bfs.nextNode(), compNum);
deba@1750
   155
	  bfs.processNextNode();
deba@1750
   156
	}
deba@1750
   157
	++compNum;
deba@1750
   158
      }
deba@1750
   159
    }
deba@1750
   160
    return compNum;
deba@1750
   161
  }
deba@1750
   162
deba@1750
   163
  namespace _topology_bits {
deba@1750
   164
deba@1750
   165
    template <typename Graph, typename Iterator >
deba@1750
   166
    struct LeaveOrderVisitor : public DfsVisitor<Graph> {
deba@1750
   167
    public:
deba@1750
   168
      typedef typename Graph::Node Node;
deba@1750
   169
      LeaveOrderVisitor(Iterator it) : _it(it) {}
deba@1750
   170
deba@1750
   171
      void leave(const Node& node) {
deba@1750
   172
	*(_it++) = node;
deba@1750
   173
      }
deba@1750
   174
deba@1750
   175
    private:
deba@1750
   176
      Iterator _it;
deba@1750
   177
    };
deba@1750
   178
deba@1750
   179
    template <typename Graph, typename Map>
deba@1750
   180
    struct FillMapVisitor : public DfsVisitor<Graph> {
deba@1750
   181
    public:
deba@1750
   182
      typedef typename Graph::Node Node;
deba@1750
   183
      typedef typename Map::Value Value;
deba@1750
   184
deba@1750
   185
      FillMapVisitor(Map& map, Value& value) 
deba@1750
   186
	: _map(map), _value(value) {}
deba@1750
   187
deba@1750
   188
      void reach(const Node& node) {
deba@1750
   189
	_map.set(node, _value);
deba@1750
   190
      }
deba@1750
   191
    private:
deba@1750
   192
      Map& _map;
deba@1750
   193
      Value& _value;
deba@1750
   194
    };
deba@1750
   195
deba@1750
   196
    template <typename Graph, typename EdgeMap>
deba@1750
   197
    struct StronglyConnectedCutEdgesVisitor : public DfsVisitor<Graph> {
deba@1750
   198
    public:
deba@1750
   199
      typedef typename Graph::Node Node;
deba@1750
   200
      typedef typename Graph::Edge Edge;
deba@1750
   201
deba@1750
   202
      StronglyConnectedCutEdgesVisitor(const Graph& graph, EdgeMap& cutMap, 
deba@1750
   203
				       int& cutNum) 
deba@1750
   204
	: _graph(graph), _cutMap(cutMap), _cutNum(cutNum), 
deba@1750
   205
	  _compMap(graph), _num(0) {
deba@1750
   206
      }
deba@1750
   207
deba@1750
   208
      void stop(const Node&) {
deba@1750
   209
	++_num;
deba@1750
   210
      }
deba@1750
   211
deba@1750
   212
      void reach(const Node& node) {
deba@1750
   213
	_compMap.set(node, _num);
deba@1750
   214
      }
deba@1750
   215
deba@1750
   216
      void examine(const Edge& edge) {
deba@1750
   217
 	if (_compMap[_graph.source(edge)] != _compMap[_graph.target(edge)]) {
deba@1750
   218
 	  _cutMap.set(edge, true);
deba@1750
   219
 	  ++_cutNum;
deba@1750
   220
 	}
deba@1750
   221
      }
deba@1750
   222
    private:
deba@1750
   223
      const Graph& _graph;
deba@1750
   224
      EdgeMap& _cutMap;
deba@1750
   225
      int& _cutNum;
deba@1750
   226
deba@1750
   227
      typename Graph::template NodeMap<int> _compMap;
deba@1750
   228
      int _num;
deba@1750
   229
    };
deba@1750
   230
deba@1750
   231
  }
deba@1750
   232
deba@1750
   233
deba@2429
   234
  /// \ingroup graph_prop
deba@1750
   235
  ///
deba@1750
   236
  /// \brief Check that the given directed graph is strongly connected.
deba@1750
   237
  ///
deba@1750
   238
  /// Check that the given directed graph is strongly connected. The
deba@1750
   239
  /// graph is strongly connected when any two nodes of the graph are
alpar@1817
   240
  /// connected with directed paths in both direction.
deba@1750
   241
  /// \return %False when the graph is not strongly connected.
deba@1750
   242
  /// \see connected
deba@1750
   243
  ///
alpar@1807
   244
  /// \note By definition, the empty graph is strongly connected.
deba@1750
   245
  template <typename Graph>
deba@1750
   246
  bool stronglyConnected(const Graph& graph) {
alpar@2260
   247
    checkConcept<concepts::Graph, Graph>();
deba@1750
   248
deba@1750
   249
    typedef typename Graph::Node Node;
deba@1750
   250
    typedef typename Graph::NodeIt NodeIt;
deba@1750
   251
deba@2082
   252
    if (NodeIt(graph) == INVALID) return true;
deba@2082
   253
deba@1750
   254
    using namespace _topology_bits;
deba@1750
   255
deba@1750
   256
    typedef DfsVisitor<Graph> Visitor;
deba@1750
   257
    Visitor visitor;
deba@1750
   258
deba@1750
   259
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@1750
   260
    dfs.init();
deba@1750
   261
    dfs.addSource(NodeIt(graph));
deba@1750
   262
    dfs.start();
deba@1750
   263
deba@1750
   264
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   265
      if (!dfs.reached(it)) {
deba@1750
   266
	return false;
deba@1750
   267
      }
deba@1750
   268
    }
deba@1750
   269
deba@1750
   270
    typedef RevGraphAdaptor<const Graph> RGraph;
deba@1750
   271
    RGraph rgraph(graph);
deba@1750
   272
deba@1750
   273
    typedef DfsVisitor<Graph> RVisitor;
deba@1750
   274
    RVisitor rvisitor;
deba@1750
   275
deba@1750
   276
    DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
deba@1750
   277
    rdfs.init();    
deba@1750
   278
    rdfs.addSource(NodeIt(graph));
deba@1750
   279
    rdfs.start();
deba@1750
   280
deba@1750
   281
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   282
      if (!rdfs.reached(it)) {
deba@1750
   283
	return false;
deba@1750
   284
      }
deba@1750
   285
    }
deba@1750
   286
deba@1750
   287
    return true;
deba@1750
   288
  }
deba@1750
   289
deba@2429
   290
  /// \ingroup graph_prop
deba@1750
   291
  ///
deba@1750
   292
  /// \brief Count the strongly connected components of a directed graph
deba@1750
   293
  ///
deba@1750
   294
  /// Count the strongly connected components of a directed graph.
deba@2421
   295
  /// The strongly connected components are the classes of an
deba@2421
   296
  /// equivalence relation on the nodes of the graph. Two nodes are in
deba@2421
   297
  /// the same class if they are connected with directed paths in both
deba@2421
   298
  /// direction. 
deba@1750
   299
  ///
deba@1793
   300
  /// \param graph The graph.
deba@1750
   301
  /// \return The number of components
alpar@1807
   302
  /// \note By definition, the empty graph has zero
alpar@1807
   303
  /// strongly connected components.
deba@1750
   304
  template <typename Graph>
deba@1750
   305
  int countStronglyConnectedComponents(const Graph& graph) {
alpar@2260
   306
    checkConcept<concepts::Graph, Graph>();
deba@1750
   307
deba@1750
   308
    using namespace _topology_bits;
deba@1750
   309
deba@1750
   310
    typedef typename Graph::Node Node;
deba@1750
   311
    typedef typename Graph::Edge Edge;
deba@1750
   312
    typedef typename Graph::NodeIt NodeIt;
deba@1750
   313
    typedef typename Graph::EdgeIt EdgeIt;
deba@1750
   314
    
deba@1750
   315
    typedef std::vector<Node> Container;
deba@1750
   316
    typedef typename Container::iterator Iterator;
deba@1750
   317
deba@1750
   318
    Container nodes(countNodes(graph));
deba@1750
   319
    typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
deba@1750
   320
    Visitor visitor(nodes.begin());
deba@1750
   321
      
deba@1750
   322
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@1750
   323
    dfs.init();
deba@1750
   324
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   325
      if (!dfs.reached(it)) {
deba@1750
   326
	dfs.addSource(it);
deba@1750
   327
	dfs.start();
deba@1750
   328
      }
deba@1750
   329
    }
deba@1750
   330
deba@1750
   331
    typedef typename Container::reverse_iterator RIterator;
deba@1750
   332
    typedef RevGraphAdaptor<const Graph> RGraph;
deba@1750
   333
deba@1750
   334
    RGraph rgraph(graph);
deba@1750
   335
deba@1750
   336
    typedef DfsVisitor<Graph> RVisitor;
deba@1750
   337
    RVisitor rvisitor;
deba@1750
   338
deba@1750
   339
    DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
deba@1750
   340
deba@1750
   341
    int compNum = 0;
deba@1750
   342
deba@1750
   343
    rdfs.init();
deba@1750
   344
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@1750
   345
      if (!rdfs.reached(*it)) {
deba@1750
   346
	rdfs.addSource(*it);
deba@1750
   347
	rdfs.start();
deba@1750
   348
	++compNum;
deba@1750
   349
      }
deba@1750
   350
    }
deba@1750
   351
    return compNum;
deba@1750
   352
  }
deba@1750
   353
deba@2429
   354
  /// \ingroup graph_prop
deba@1750
   355
  ///
deba@1750
   356
  /// \brief Find the strongly connected components of a directed graph
deba@1750
   357
  ///
deba@2421
   358
  /// Find the strongly connected components of a directed graph.  The
deba@2421
   359
  /// strongly connected components are the classes of an equivalence
deba@2421
   360
  /// relation on the nodes of the graph. Two nodes are in
deba@2421
   361
  /// relationship when there are directed paths between them in both
deba@2421
   362
  /// direction. In addition, the numbering of components will satisfy
deba@2421
   363
  /// that there is no edge going from a higher numbered component to
deba@2421
   364
  /// a lower.
deba@1750
   365
  ///
deba@1763
   366
  /// \image html strongly_connected_components.png
deba@1763
   367
  /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
deba@1763
   368
  ///
deba@1793
   369
  /// \param graph The graph.
deba@1793
   370
  /// \retval compMap A writable node map. The values will be set from 0 to
deba@2421
   371
  /// the number of the strongly connected components minus one. Each value 
deba@1750
   372
  /// of the map will be set exactly once, the values of a certain component 
deba@1750
   373
  /// will be set continuously.
deba@1750
   374
  /// \return The number of components
deba@1763
   375
  ///
deba@1750
   376
  template <typename Graph, typename NodeMap>
deba@1750
   377
  int stronglyConnectedComponents(const Graph& graph, NodeMap& compMap) {
alpar@2260
   378
    checkConcept<concepts::Graph, Graph>();
deba@1750
   379
    typedef typename Graph::Node Node;
deba@1750
   380
    typedef typename Graph::NodeIt NodeIt;
alpar@2260
   381
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
deba@1750
   382
deba@1750
   383
    using namespace _topology_bits;
deba@1750
   384
    
deba@1750
   385
    typedef std::vector<Node> Container;
deba@1750
   386
    typedef typename Container::iterator Iterator;
deba@1750
   387
deba@1750
   388
    Container nodes(countNodes(graph));
deba@1750
   389
    typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
deba@1750
   390
    Visitor visitor(nodes.begin());
deba@1750
   391
      
deba@1750
   392
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@1750
   393
    dfs.init();
deba@1750
   394
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   395
      if (!dfs.reached(it)) {
deba@1750
   396
	dfs.addSource(it);
deba@1750
   397
	dfs.start();
deba@1750
   398
      }
deba@1750
   399
    }
deba@1750
   400
deba@1750
   401
    typedef typename Container::reverse_iterator RIterator;
deba@1750
   402
    typedef RevGraphAdaptor<const Graph> RGraph;
deba@1750
   403
deba@1750
   404
    RGraph rgraph(graph);
deba@1750
   405
deba@1750
   406
    int compNum = 0;
deba@1750
   407
deba@1750
   408
    typedef FillMapVisitor<RGraph, NodeMap> RVisitor;
deba@1750
   409
    RVisitor rvisitor(compMap, compNum);
deba@1750
   410
deba@1750
   411
    DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
deba@1750
   412
deba@1750
   413
    rdfs.init();
deba@1750
   414
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@1750
   415
      if (!rdfs.reached(*it)) {
deba@1750
   416
	rdfs.addSource(*it);
deba@1750
   417
	rdfs.start();
deba@1750
   418
	++compNum;
deba@1750
   419
      }
deba@1750
   420
    }
deba@1750
   421
    return compNum;
deba@1750
   422
  }
deba@1750
   423
deba@2429
   424
  /// \ingroup graph_prop
deba@1750
   425
  ///
deba@1750
   426
  /// \brief Find the cut edges of the strongly connected components.
deba@1750
   427
  ///
deba@1750
   428
  /// Find the cut edges of the strongly connected components.
deba@1750
   429
  /// The strongly connected components are the classes of an equivalence
deba@1750
   430
  /// relation on the nodes of the graph. Two nodes are in relationship
deba@1750
   431
  /// when there are directed paths between them in both direction.
deba@1750
   432
  /// The strongly connected components are separated by the cut edges.
deba@1750
   433
  ///
deba@1793
   434
  /// \param graph The graph.
deba@1793
   435
  /// \retval cutMap A writable node map. The values will be set true when the
deba@1793
   436
  /// edge is a cut edge.
deba@1750
   437
  ///
deba@1750
   438
  /// \return The number of cut edges
deba@1750
   439
  template <typename Graph, typename EdgeMap>
deba@1750
   440
  int stronglyConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
alpar@2260
   441
    checkConcept<concepts::Graph, Graph>();
deba@1750
   442
    typedef typename Graph::Node Node;
deba@1750
   443
    typedef typename Graph::Edge Edge;
deba@1750
   444
    typedef typename Graph::NodeIt NodeIt;
alpar@2260
   445
    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
deba@1750
   446
deba@1750
   447
    using namespace _topology_bits;
deba@1750
   448
    
deba@1750
   449
    typedef std::vector<Node> Container;
deba@1750
   450
    typedef typename Container::iterator Iterator;
deba@1750
   451
deba@1750
   452
    Container nodes(countNodes(graph));
deba@1750
   453
    typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
deba@1750
   454
    Visitor visitor(nodes.begin());
deba@1750
   455
      
deba@1750
   456
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@1750
   457
    dfs.init();
deba@1750
   458
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   459
      if (!dfs.reached(it)) {
deba@1750
   460
	dfs.addSource(it);
deba@1750
   461
	dfs.start();
deba@1750
   462
      }
deba@1750
   463
    }
deba@1750
   464
deba@1750
   465
    typedef typename Container::reverse_iterator RIterator;
deba@1750
   466
    typedef RevGraphAdaptor<const Graph> RGraph;
deba@1750
   467
deba@1750
   468
    RGraph rgraph(graph);
deba@1750
   469
deba@1750
   470
    int cutNum = 0;
deba@1750
   471
deba@1750
   472
    typedef StronglyConnectedCutEdgesVisitor<RGraph, EdgeMap> RVisitor;
deba@1750
   473
    RVisitor rvisitor(rgraph, cutMap, cutNum);
deba@1750
   474
deba@1750
   475
    DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
deba@1750
   476
deba@1750
   477
    rdfs.init();
deba@1750
   478
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@1750
   479
      if (!rdfs.reached(*it)) {
deba@1750
   480
	rdfs.addSource(*it);
deba@1750
   481
	rdfs.start();
deba@1750
   482
      }
deba@1750
   483
    }
deba@1750
   484
    return cutNum;
deba@1750
   485
  }
deba@1750
   486
deba@1698
   487
  namespace _topology_bits {
deba@1698
   488
    
deba@1750
   489
    template <typename Graph>
deba@1800
   490
    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Graph> {
deba@1698
   491
    public:
deba@1750
   492
      typedef typename Graph::Node Node;
deba@1750
   493
      typedef typename Graph::Edge Edge;
klao@1909
   494
      typedef typename Graph::UEdge UEdge;
deba@1698
   495
deba@1800
   496
      CountBiNodeConnectedComponentsVisitor(const Graph& graph, int &compNum) 
deba@1750
   497
	: _graph(graph), _compNum(compNum), 
deba@1750
   498
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   499
deba@1750
   500
      void start(const Node& node) {
deba@1750
   501
	_predMap.set(node, INVALID);
deba@1750
   502
      }
deba@1750
   503
      
deba@1750
   504
      void reach(const Node& node) {
deba@1750
   505
	_numMap.set(node, _num);
deba@1750
   506
	_retMap.set(node, _num);
deba@1750
   507
	++_num;
deba@1750
   508
      }
deba@1750
   509
deba@1750
   510
      void discover(const Edge& edge) {
deba@1750
   511
	_predMap.set(_graph.target(edge), _graph.source(edge));
deba@1750
   512
      }
deba@1750
   513
deba@1750
   514
      void examine(const Edge& edge) {
deba@1750
   515
	if (_graph.source(edge) == _graph.target(edge) && 
deba@1750
   516
	    _graph.direction(edge)) {
deba@1750
   517
	  ++_compNum;
deba@1750
   518
	  return;
deba@1750
   519
	}
deba@1750
   520
	if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
deba@1750
   521
	  return;
deba@1750
   522
	}
deba@1750
   523
	if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
deba@1750
   524
	  _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
deba@1698
   525
	}
deba@1698
   526
      }
deba@1698
   527
deba@1750
   528
      void backtrack(const Edge& edge) {
deba@1750
   529
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   530
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   531
	}  
deba@1750
   532
	if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
deba@1750
   533
	  ++_compNum;
deba@1750
   534
	}
deba@1750
   535
      }
deba@1750
   536
      
deba@1750
   537
    private:
deba@1750
   538
      const Graph& _graph;
deba@1750
   539
      int& _compNum; 
deba@1750
   540
deba@1750
   541
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   542
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   543
      typename Graph::template NodeMap<Node> _predMap;
deba@1750
   544
      int _num;
deba@1750
   545
    };
deba@1750
   546
deba@1750
   547
    template <typename Graph, typename EdgeMap>
deba@1800
   548
    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Graph> {
deba@1750
   549
    public:
deba@1750
   550
      typedef typename Graph::Node Node;
deba@1750
   551
      typedef typename Graph::Edge Edge;
klao@1909
   552
      typedef typename Graph::UEdge UEdge;
deba@1750
   553
deba@1800
   554
      BiNodeConnectedComponentsVisitor(const Graph& graph, 
deba@1750
   555
				       EdgeMap& compMap, int &compNum) 
deba@1750
   556
	: _graph(graph), _compMap(compMap), _compNum(compNum), 
deba@1750
   557
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   558
deba@1750
   559
      void start(const Node& node) {
deba@1750
   560
	_predMap.set(node, INVALID);
deba@1750
   561
      }
deba@1750
   562
      
deba@1750
   563
      void reach(const Node& node) {
deba@1750
   564
	_numMap.set(node, _num);
deba@1750
   565
	_retMap.set(node, _num);
deba@1750
   566
	++_num;
deba@1750
   567
      }
deba@1750
   568
deba@1750
   569
      void discover(const Edge& edge) {
deba@1750
   570
	Node target = _graph.target(edge);
deba@1750
   571
	_predMap.set(target, edge);
deba@1750
   572
	_edgeStack.push(edge);
deba@1750
   573
      }
deba@1750
   574
deba@1750
   575
      void examine(const Edge& edge) {
deba@1750
   576
	Node source = _graph.source(edge);
deba@1750
   577
	Node target = _graph.target(edge);
deba@1750
   578
	if (source == target && _graph.direction(edge)) {
deba@1750
   579
	  _compMap.set(edge, _compNum);
deba@1750
   580
	  ++_compNum;
deba@1750
   581
	  return;
deba@1750
   582
	}
deba@1750
   583
	if (_numMap[target] < _numMap[source]) {
deba@1750
   584
	  if (_predMap[source] != _graph.oppositeEdge(edge)) {
deba@1750
   585
	    _edgeStack.push(edge);
deba@1750
   586
	  }
deba@1750
   587
	}
deba@1750
   588
	if (_predMap[source] != INVALID && 
deba@1750
   589
	    target == _graph.source(_predMap[source])) {
deba@1750
   590
	  return;
deba@1750
   591
	}
deba@1750
   592
	if (_retMap[source] > _numMap[target]) {
deba@1750
   593
	  _retMap.set(source, _numMap[target]);
deba@1750
   594
	}
deba@1750
   595
      }
deba@1750
   596
deba@1750
   597
      void backtrack(const Edge& edge) {
deba@1750
   598
	Node source = _graph.source(edge);
deba@1750
   599
	Node target = _graph.target(edge);
deba@1750
   600
	if (_retMap[source] > _retMap[target]) {
deba@1750
   601
	  _retMap.set(source, _retMap[target]);
deba@1750
   602
	}  
deba@1750
   603
	if (_numMap[source] <= _retMap[target]) {
deba@1750
   604
	  while (_edgeStack.top() != edge) {
deba@1750
   605
	    _compMap.set(_edgeStack.top(), _compNum);
deba@1750
   606
	    _edgeStack.pop();
deba@1750
   607
	  }
deba@1750
   608
	  _compMap.set(edge, _compNum);
deba@1750
   609
	  _edgeStack.pop();
deba@1750
   610
	  ++_compNum;
deba@1750
   611
	}
deba@1750
   612
      }
deba@1750
   613
      
deba@1750
   614
    private:
deba@1750
   615
      const Graph& _graph;
deba@1750
   616
      EdgeMap& _compMap;
deba@1750
   617
      int& _compNum; 
deba@1750
   618
deba@1750
   619
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   620
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   621
      typename Graph::template NodeMap<Edge> _predMap;
klao@1909
   622
      std::stack<UEdge> _edgeStack;
deba@1750
   623
      int _num;
deba@1750
   624
    };
deba@1750
   625
deba@1750
   626
deba@1750
   627
    template <typename Graph, typename NodeMap>
deba@1800
   628
    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Graph> {
deba@1750
   629
    public:
deba@1750
   630
      typedef typename Graph::Node Node;
deba@1750
   631
      typedef typename Graph::Edge Edge;
klao@1909
   632
      typedef typename Graph::UEdge UEdge;
deba@1750
   633
deba@1800
   634
      BiNodeConnectedCutNodesVisitor(const Graph& graph, NodeMap& cutMap,
deba@1750
   635
				     int& cutNum) 
deba@1750
   636
	: _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
deba@1750
   637
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   638
deba@1750
   639
      void start(const Node& node) {
deba@1750
   640
	_predMap.set(node, INVALID);
deba@1750
   641
	rootCut = false;
deba@1750
   642
      }
deba@1750
   643
      
deba@1750
   644
      void reach(const Node& node) {
deba@1750
   645
	_numMap.set(node, _num);
deba@1750
   646
	_retMap.set(node, _num);
deba@1750
   647
	++_num;
deba@1750
   648
      }
deba@1750
   649
deba@1750
   650
      void discover(const Edge& edge) {
deba@1750
   651
	_predMap.set(_graph.target(edge), _graph.source(edge));
deba@1750
   652
      }
deba@1750
   653
deba@1750
   654
      void examine(const Edge& edge) {
deba@1750
   655
	if (_graph.source(edge) == _graph.target(edge) && 
deba@1750
   656
	    _graph.direction(edge)) {
deba@1750
   657
	  if (!_cutMap[_graph.source(edge)]) {
deba@1750
   658
	    _cutMap.set(_graph.source(edge), true);
deba@1750
   659
	    ++_cutNum;
deba@1750
   660
	  }
deba@1750
   661
	  return;
deba@1750
   662
	}
deba@1750
   663
	if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
deba@1750
   664
	if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
deba@1750
   665
	  _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
deba@1750
   666
	}
deba@1750
   667
      }
deba@1750
   668
deba@1750
   669
      void backtrack(const Edge& edge) {
deba@1750
   670
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   671
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   672
	}  
deba@1750
   673
	if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
deba@1750
   674
	  if (_predMap[_graph.source(edge)] != INVALID) {
deba@1750
   675
	    if (!_cutMap[_graph.source(edge)]) {
deba@1750
   676
	      _cutMap.set(_graph.source(edge), true);
deba@1750
   677
	      ++_cutNum;
deba@1750
   678
	    }
deba@1750
   679
	  } else if (rootCut) {
deba@1750
   680
	    if (!_cutMap[_graph.source(edge)]) {
deba@1750
   681
	      _cutMap.set(_graph.source(edge), true);
deba@1750
   682
	      ++_cutNum;
deba@1750
   683
	    }
deba@1750
   684
	  } else {
deba@1750
   685
	    rootCut = true;
deba@1750
   686
	  }
deba@1750
   687
	}
deba@1750
   688
      }
deba@1750
   689
      
deba@1750
   690
    private:
deba@1750
   691
      const Graph& _graph;
deba@1750
   692
      NodeMap& _cutMap;
deba@1750
   693
      int& _cutNum; 
deba@1750
   694
deba@1750
   695
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   696
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   697
      typename Graph::template NodeMap<Node> _predMap;
klao@1909
   698
      std::stack<UEdge> _edgeStack;
deba@1750
   699
      int _num;
deba@1750
   700
      bool rootCut;
deba@1750
   701
    };
deba@1750
   702
deba@1750
   703
  }
deba@1750
   704
klao@1909
   705
  template <typename UGraph>
klao@1909
   706
  int countBiNodeConnectedComponents(const UGraph& graph);
deba@1750
   707
deba@2429
   708
  /// \ingroup graph_prop
deba@1750
   709
  ///
deba@1767
   710
  /// \brief Checks the graph is bi-node-connected.
deba@1750
   711
  ///
deba@1767
   712
  /// This function checks that the undirected graph is bi-node-connected  
deba@1767
   713
  /// graph. The graph is bi-node-connected if any two undirected edge is 
deba@1750
   714
  /// on same circle.
deba@1750
   715
  ///
deba@1750
   716
  /// \param graph The graph.
deba@1767
   717
  /// \return %True when the graph bi-node-connected.
klao@1909
   718
  template <typename UGraph>
klao@1909
   719
  bool biNodeConnected(const UGraph& graph) {
deba@1800
   720
    return countBiNodeConnectedComponents(graph) == 1;
deba@1750
   721
  }
deba@1750
   722
deba@2429
   723
  /// \ingroup graph_prop
deba@1750
   724
  ///
deba@1750
   725
  /// \brief Count the biconnected components.
deba@1750
   726
  ///
deba@1767
   727
  /// This function finds the bi-node-connected components in an undirected 
deba@1750
   728
  /// graph. The biconnected components are the classes of an equivalence 
deba@1750
   729
  /// relation on the undirected edges. Two undirected edge is in relationship
deba@1750
   730
  /// when they are on same circle.
deba@1750
   731
  ///
deba@1750
   732
  /// \param graph The graph.
deba@1750
   733
  /// \return The number of components.
klao@1909
   734
  template <typename UGraph>
klao@1909
   735
  int countBiNodeConnectedComponents(const UGraph& graph) {
alpar@2260
   736
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
   737
    typedef typename UGraph::NodeIt NodeIt;
deba@1750
   738
deba@1750
   739
    using namespace _topology_bits;
deba@1750
   740
klao@1909
   741
    typedef CountBiNodeConnectedComponentsVisitor<UGraph> Visitor;
deba@1750
   742
deba@1750
   743
    int compNum = 0;
deba@1750
   744
    Visitor visitor(graph, compNum);
deba@1750
   745
klao@1909
   746
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
   747
    dfs.init();
deba@1750
   748
    
deba@1750
   749
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   750
      if (!dfs.reached(it)) {
deba@1750
   751
	dfs.addSource(it);
deba@1750
   752
	dfs.start();
deba@1750
   753
      }
deba@1750
   754
    }
deba@1750
   755
    return compNum;
deba@1750
   756
  }
deba@1750
   757
deba@2429
   758
  /// \ingroup graph_prop
deba@1750
   759
  ///
deba@1767
   760
  /// \brief Find the bi-node-connected components.
deba@1750
   761
  ///
deba@1767
   762
  /// This function finds the bi-node-connected components in an undirected 
deba@1767
   763
  /// graph. The bi-node-connected components are the classes of an equivalence
deba@1750
   764
  /// relation on the undirected edges. Two undirected edge are in relationship
deba@1750
   765
  /// when they are on same circle.
deba@1750
   766
  ///
deba@1763
   767
  /// \image html node_biconnected_components.png
deba@1767
   768
  /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
deba@1763
   769
  ///
deba@1750
   770
  /// \param graph The graph.
klao@1909
   771
  /// \retval compMap A writable uedge map. The values will be set from 0
deba@1793
   772
  /// to the number of the biconnected components minus one. Each values 
deba@1750
   773
  /// of the map will be set exactly once, the values of a certain component 
deba@1750
   774
  /// will be set continuously.
deba@1750
   775
  /// \return The number of components.
deba@1763
   776
  ///
klao@1909
   777
  template <typename UGraph, typename UEdgeMap>
klao@1909
   778
  int biNodeConnectedComponents(const UGraph& graph, 
klao@1909
   779
				UEdgeMap& compMap) {
alpar@2260
   780
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
   781
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
   782
    typedef typename UGraph::UEdge UEdge;
alpar@2260
   783
    checkConcept<concepts::WriteMap<UEdge, int>, UEdgeMap>();
deba@1750
   784
deba@1750
   785
    using namespace _topology_bits;
deba@1750
   786
klao@1909
   787
    typedef BiNodeConnectedComponentsVisitor<UGraph, UEdgeMap> Visitor;
deba@1750
   788
    
deba@1750
   789
    int compNum = 0;
deba@1750
   790
    Visitor visitor(graph, compMap, compNum);
deba@1750
   791
klao@1909
   792
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
   793
    dfs.init();
deba@1750
   794
    
deba@1750
   795
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   796
      if (!dfs.reached(it)) {
deba@1750
   797
	dfs.addSource(it);
deba@1750
   798
	dfs.start();
deba@1750
   799
      }
deba@1750
   800
    }
deba@1750
   801
    return compNum;
deba@1750
   802
  }
deba@1750
   803
deba@2429
   804
  /// \ingroup graph_prop
deba@1750
   805
  ///
deba@1767
   806
  /// \brief Find the bi-node-connected cut nodes.
deba@1750
   807
  ///
deba@1767
   808
  /// This function finds the bi-node-connected cut nodes in an undirected 
deba@1767
   809
  /// graph. The bi-node-connected components are the classes of an equivalence
deba@1750
   810
  /// relation on the undirected edges. Two undirected edges are in 
deba@1750
   811
  /// relationship when they are on same circle. The biconnected components 
deba@1750
   812
  /// are separted by nodes which are the cut nodes of the components.
deba@1750
   813
  ///
deba@1750
   814
  /// \param graph The graph.
deba@1793
   815
  /// \retval cutMap A writable edge map. The values will be set true when
deba@1750
   816
  /// the node separate two or more components.
deba@1750
   817
  /// \return The number of the cut nodes.
klao@1909
   818
  template <typename UGraph, typename NodeMap>
klao@1909
   819
  int biNodeConnectedCutNodes(const UGraph& graph, NodeMap& cutMap) {
alpar@2260
   820
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
   821
    typedef typename UGraph::Node Node;
klao@1909
   822
    typedef typename UGraph::NodeIt NodeIt;
alpar@2260
   823
    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
deba@1750
   824
deba@1750
   825
    using namespace _topology_bits;
deba@1750
   826
klao@1909
   827
    typedef BiNodeConnectedCutNodesVisitor<UGraph, NodeMap> Visitor;
deba@1750
   828
    
deba@1750
   829
    int cutNum = 0;
deba@1750
   830
    Visitor visitor(graph, cutMap, cutNum);
deba@1750
   831
klao@1909
   832
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
   833
    dfs.init();
deba@1750
   834
    
deba@1750
   835
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   836
      if (!dfs.reached(it)) {
deba@1750
   837
	dfs.addSource(it);
deba@1750
   838
	dfs.start();
deba@1750
   839
      }
deba@1750
   840
    }
deba@1750
   841
    return cutNum;
deba@1750
   842
  }
deba@1750
   843
deba@1750
   844
  namespace _topology_bits {
deba@1750
   845
    
deba@1750
   846
    template <typename Graph>
deba@1800
   847
    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Graph> {
deba@1750
   848
    public:
deba@1750
   849
      typedef typename Graph::Node Node;
deba@1750
   850
      typedef typename Graph::Edge Edge;
klao@1909
   851
      typedef typename Graph::UEdge UEdge;
deba@1750
   852
deba@1800
   853
      CountBiEdgeConnectedComponentsVisitor(const Graph& graph, int &compNum) 
deba@1750
   854
	: _graph(graph), _compNum(compNum), 
deba@1750
   855
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   856
deba@1750
   857
      void start(const Node& node) {
deba@1750
   858
	_predMap.set(node, INVALID);
deba@1750
   859
      }
deba@1750
   860
      
deba@1750
   861
      void reach(const Node& node) {
deba@1750
   862
	_numMap.set(node, _num);
deba@1750
   863
	_retMap.set(node, _num);
deba@1750
   864
	++_num;
deba@1750
   865
      }
deba@1750
   866
      
deba@1750
   867
      void leave(const Node& node) {
deba@1750
   868
	if (_numMap[node] <= _retMap[node]) {
deba@1750
   869
	  ++_compNum;
deba@1750
   870
	}	
deba@1750
   871
      }
deba@1750
   872
deba@1750
   873
      void discover(const Edge& edge) {
deba@1750
   874
	_predMap.set(_graph.target(edge), edge);
deba@1750
   875
      }
deba@1750
   876
deba@1750
   877
      void examine(const Edge& edge) {
deba@1750
   878
	if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
deba@1750
   879
	  return;
deba@1750
   880
	}
deba@1750
   881
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   882
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   883
	}
deba@1750
   884
      }
deba@1750
   885
deba@1750
   886
      void backtrack(const Edge& edge) {
deba@1750
   887
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   888
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   889
	}  
deba@1750
   890
      }
deba@1750
   891
      
deba@1750
   892
    private:
deba@1750
   893
      const Graph& _graph;
deba@1750
   894
      int& _compNum; 
deba@1750
   895
deba@1750
   896
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   897
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   898
      typename Graph::template NodeMap<Edge> _predMap;
deba@1750
   899
      int _num;
deba@1750
   900
    };
deba@1750
   901
deba@1750
   902
    template <typename Graph, typename NodeMap>
deba@1800
   903
    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Graph> {
deba@1750
   904
    public:
deba@1750
   905
      typedef typename Graph::Node Node;
deba@1750
   906
      typedef typename Graph::Edge Edge;
klao@1909
   907
      typedef typename Graph::UEdge UEdge;
deba@1750
   908
deba@1800
   909
      BiEdgeConnectedComponentsVisitor(const Graph& graph, 
deba@1750
   910
				       NodeMap& compMap, int &compNum) 
deba@1750
   911
	: _graph(graph), _compMap(compMap), _compNum(compNum), 
deba@1750
   912
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   913
deba@1750
   914
      void start(const Node& node) {
deba@1750
   915
	_predMap.set(node, INVALID);
deba@1750
   916
      }
deba@1750
   917
      
deba@1750
   918
      void reach(const Node& node) {
deba@1750
   919
	_numMap.set(node, _num);
deba@1750
   920
	_retMap.set(node, _num);
deba@1750
   921
	_nodeStack.push(node);
deba@1750
   922
	++_num;
deba@1750
   923
      }
deba@1750
   924
      
deba@1750
   925
      void leave(const Node& node) {
deba@1750
   926
	if (_numMap[node] <= _retMap[node]) {
deba@1750
   927
	  while (_nodeStack.top() != node) {
deba@1750
   928
	    _compMap.set(_nodeStack.top(), _compNum);
deba@1750
   929
	    _nodeStack.pop();
deba@1750
   930
	  }
deba@1750
   931
	  _compMap.set(node, _compNum);
deba@1750
   932
	  _nodeStack.pop();
deba@1750
   933
	  ++_compNum;
deba@1750
   934
	}	
deba@1750
   935
      }
deba@1750
   936
deba@1750
   937
      void discover(const Edge& edge) {
deba@1750
   938
	_predMap.set(_graph.target(edge), edge);
deba@1750
   939
      }
deba@1750
   940
deba@1750
   941
      void examine(const Edge& edge) {
deba@1750
   942
	if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
deba@1750
   943
	  return;
deba@1750
   944
	}
deba@1750
   945
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   946
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   947
	}
deba@1750
   948
      }
deba@1750
   949
deba@1750
   950
      void backtrack(const Edge& edge) {
deba@1750
   951
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   952
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   953
	}  
deba@1750
   954
      }
deba@1750
   955
      
deba@1750
   956
    private:
deba@1750
   957
      const Graph& _graph;
deba@1750
   958
      NodeMap& _compMap;
deba@1750
   959
      int& _compNum; 
deba@1750
   960
deba@1750
   961
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   962
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   963
      typename Graph::template NodeMap<Edge> _predMap;
deba@1750
   964
      std::stack<Node> _nodeStack;
deba@1750
   965
      int _num;
deba@1750
   966
    };
deba@1750
   967
deba@1750
   968
deba@1750
   969
    template <typename Graph, typename EdgeMap>
deba@1800
   970
    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Graph> {
deba@1750
   971
    public:
deba@1750
   972
      typedef typename Graph::Node Node;
deba@1750
   973
      typedef typename Graph::Edge Edge;
klao@1909
   974
      typedef typename Graph::UEdge UEdge;
deba@1750
   975
deba@1800
   976
      BiEdgeConnectedCutEdgesVisitor(const Graph& graph, 
deba@1750
   977
				     EdgeMap& cutMap, int &cutNum) 
deba@1750
   978
	: _graph(graph), _cutMap(cutMap), _cutNum(cutNum), 
deba@1750
   979
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   980
deba@1750
   981
      void start(const Node& node) {
deba@1750
   982
	_predMap[node] = INVALID;
deba@1750
   983
      }
deba@1750
   984
      
deba@1750
   985
      void reach(const Node& node) {
deba@1750
   986
	_numMap.set(node, _num);
deba@1750
   987
	_retMap.set(node, _num);
deba@1750
   988
	++_num;
deba@1750
   989
      }
deba@1750
   990
      
deba@1750
   991
      void leave(const Node& node) {
deba@1750
   992
	if (_numMap[node] <= _retMap[node]) {
deba@1750
   993
	  if (_predMap[node] != INVALID) {
deba@1750
   994
	    _cutMap.set(_predMap[node], true);
deba@1750
   995
	    ++_cutNum;
deba@1750
   996
	  }
deba@1750
   997
	}	
deba@1750
   998
      }
deba@1750
   999
deba@1750
  1000
      void discover(const Edge& edge) {
deba@1750
  1001
	_predMap.set(_graph.target(edge), edge);
deba@1750
  1002
      }
deba@1750
  1003
deba@1750
  1004
      void examine(const Edge& edge) {
deba@1750
  1005
	if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
deba@1750
  1006
	  return;
deba@1750
  1007
	}
deba@1750
  1008
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
  1009
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
  1010
	}
deba@1750
  1011
      }
deba@1750
  1012
deba@1750
  1013
      void backtrack(const Edge& edge) {
deba@1750
  1014
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
  1015
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
  1016
	}  
deba@1750
  1017
      }
deba@1750
  1018
      
deba@1750
  1019
    private:
deba@1750
  1020
      const Graph& _graph;
deba@1750
  1021
      EdgeMap& _cutMap;
deba@1750
  1022
      int& _cutNum; 
deba@1750
  1023
deba@1750
  1024
      typename Graph::template NodeMap<int> _numMap;
deba@1750
  1025
      typename Graph::template NodeMap<int> _retMap;
deba@1750
  1026
      typename Graph::template NodeMap<Edge> _predMap;
deba@1750
  1027
      int _num;
deba@1750
  1028
    };
deba@1750
  1029
  }
deba@1750
  1030
klao@1909
  1031
  template <typename UGraph>
deba@2421
  1032
  int countBiEdgeConnectedComponents(const UGraph& graph);
deba@1750
  1033
deba@2429
  1034
  /// \ingroup graph_prop
deba@1750
  1035
  ///
deba@1767
  1036
  /// \brief Checks that the graph is bi-edge-connected.
deba@1750
  1037
  ///
deba@1767
  1038
  /// This function checks that the graph is bi-edge-connected. The undirected
deba@1767
  1039
  /// graph is bi-edge-connected when any two nodes are connected with two
deba@1750
  1040
  /// edge-disjoint paths.
deba@1750
  1041
  ///
deba@1750
  1042
  /// \param graph The undirected graph.
deba@1750
  1043
  /// \return The number of components.
klao@1909
  1044
  template <typename UGraph>
klao@1909
  1045
  bool biEdgeConnected(const UGraph& graph) { 
deba@1800
  1046
    return countBiEdgeConnectedComponents(graph) == 1;
deba@1750
  1047
  }
deba@1750
  1048
deba@2429
  1049
  /// \ingroup graph_prop
deba@1750
  1050
  ///
deba@1767
  1051
  /// \brief Count the bi-edge-connected components.
deba@1750
  1052
  ///
deba@1767
  1053
  /// This function count the bi-edge-connected components in an undirected 
deba@1767
  1054
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@1750
  1055
  /// relation on the nodes. Two nodes are in relationship when they are  
deba@1750
  1056
  /// connected with at least two edge-disjoint paths.
deba@1750
  1057
  ///
deba@1750
  1058
  /// \param graph The undirected graph.
deba@1750
  1059
  /// \return The number of components.
klao@1909
  1060
  template <typename UGraph>
klao@1909
  1061
  int countBiEdgeConnectedComponents(const UGraph& graph) { 
alpar@2260
  1062
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1063
    typedef typename UGraph::NodeIt NodeIt;
deba@1750
  1064
deba@1750
  1065
    using namespace _topology_bits;
deba@1750
  1066
klao@1909
  1067
    typedef CountBiEdgeConnectedComponentsVisitor<UGraph> Visitor;
deba@1750
  1068
    
deba@1750
  1069
    int compNum = 0;
deba@1750
  1070
    Visitor visitor(graph, compNum);
deba@1750
  1071
klao@1909
  1072
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
  1073
    dfs.init();
deba@1750
  1074
    
deba@1750
  1075
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
  1076
      if (!dfs.reached(it)) {
deba@1750
  1077
	dfs.addSource(it);
deba@1750
  1078
	dfs.start();
deba@1750
  1079
      }
deba@1750
  1080
    }
deba@1750
  1081
    return compNum;
deba@1750
  1082
  }
deba@1750
  1083
deba@2429
  1084
  /// \ingroup graph_prop
deba@1750
  1085
  ///
deba@1767
  1086
  /// \brief Find the bi-edge-connected components.
deba@1750
  1087
  ///
deba@1767
  1088
  /// This function finds the bi-edge-connected components in an undirected 
deba@1767
  1089
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@1750
  1090
  /// relation on the nodes. Two nodes are in relationship when they are  
deba@1750
  1091
  /// connected at least two edge-disjoint paths.
deba@1750
  1092
  ///
deba@1763
  1093
  /// \image html edge_biconnected_components.png
deba@1767
  1094
  /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
deba@1763
  1095
  ///
deba@1750
  1096
  /// \param graph The graph.
deba@1793
  1097
  /// \retval compMap A writable node map. The values will be set from 0 to
deba@1750
  1098
  /// the number of the biconnected components minus one. Each values 
deba@1750
  1099
  /// of the map will be set exactly once, the values of a certain component 
deba@1750
  1100
  /// will be set continuously.
deba@1750
  1101
  /// \return The number of components.
deba@1763
  1102
  ///
klao@1909
  1103
  template <typename UGraph, typename NodeMap>
klao@1909
  1104
  int biEdgeConnectedComponents(const UGraph& graph, NodeMap& compMap) { 
alpar@2260
  1105
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1106
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1107
    typedef typename UGraph::Node Node;
alpar@2260
  1108
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
deba@1750
  1109
deba@1750
  1110
    using namespace _topology_bits;
deba@1750
  1111
klao@1909
  1112
    typedef BiEdgeConnectedComponentsVisitor<UGraph, NodeMap> Visitor;
deba@1750
  1113
    
deba@1750
  1114
    int compNum = 0;
deba@1750
  1115
    Visitor visitor(graph, compMap, compNum);
deba@1750
  1116
klao@1909
  1117
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
  1118
    dfs.init();
deba@1750
  1119
    
deba@1750
  1120
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
  1121
      if (!dfs.reached(it)) {
deba@1750
  1122
	dfs.addSource(it);
deba@1750
  1123
	dfs.start();
deba@1750
  1124
      }
deba@1750
  1125
    }
deba@1750
  1126
    return compNum;
deba@1750
  1127
  }
deba@1750
  1128
deba@2429
  1129
  /// \ingroup graph_prop
deba@1750
  1130
  ///
deba@1767
  1131
  /// \brief Find the bi-edge-connected cut edges.
deba@1750
  1132
  ///
deba@1767
  1133
  /// This function finds the bi-edge-connected components in an undirected 
deba@1767
  1134
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@1750
  1135
  /// relation on the nodes. Two nodes are in relationship when they are 
deba@1767
  1136
  /// connected with at least two edge-disjoint paths. The bi-edge-connected 
deba@1750
  1137
  /// components are separted by edges which are the cut edges of the 
deba@1750
  1138
  /// components.
deba@1750
  1139
  ///
deba@1750
  1140
  /// \param graph The graph.
deba@1793
  1141
  /// \retval cutMap A writable node map. The values will be set true when the
deba@1750
  1142
  /// edge is a cut edge.
deba@1750
  1143
  /// \return The number of cut edges.
klao@1909
  1144
  template <typename UGraph, typename UEdgeMap>
klao@1909
  1145
  int biEdgeConnectedCutEdges(const UGraph& graph, UEdgeMap& cutMap) { 
alpar@2260
  1146
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1147
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1148
    typedef typename UGraph::UEdge UEdge;
alpar@2260
  1149
    checkConcept<concepts::WriteMap<UEdge, bool>, UEdgeMap>();
deba@1750
  1150
deba@1750
  1151
    using namespace _topology_bits;
deba@1750
  1152
klao@1909
  1153
    typedef BiEdgeConnectedCutEdgesVisitor<UGraph, UEdgeMap> Visitor;
deba@1750
  1154
    
deba@1750
  1155
    int cutNum = 0;
deba@1750
  1156
    Visitor visitor(graph, cutMap, cutNum);
deba@1750
  1157
klao@1909
  1158
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
  1159
    dfs.init();
deba@1750
  1160
    
deba@1750
  1161
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
  1162
      if (!dfs.reached(it)) {
deba@1750
  1163
	dfs.addSource(it);
deba@1750
  1164
	dfs.start();
deba@1750
  1165
      }
deba@1750
  1166
    }
deba@1750
  1167
    return cutNum;
deba@1750
  1168
  }
deba@1750
  1169
deba@1750
  1170
deba@1750
  1171
  namespace _topology_bits {
deba@1750
  1172
    
deba@1750
  1173
    template <typename Graph, typename IntNodeMap>
deba@1750
  1174
    class TopologicalSortVisitor : public DfsVisitor<Graph> {
deba@1750
  1175
    public:
deba@1750
  1176
      typedef typename Graph::Node Node;
deba@1750
  1177
      typedef typename Graph::Edge edge;
deba@1750
  1178
deba@1750
  1179
      TopologicalSortVisitor(IntNodeMap& order, int num) 
deba@1750
  1180
	: _order(order), _num(num) {}
deba@1750
  1181
      
deba@1750
  1182
      void leave(const Node& node) {
deba@1750
  1183
	_order.set(node, --_num);
deba@1698
  1184
      }
deba@1698
  1185
deba@1698
  1186
    private:
deba@1750
  1187
      IntNodeMap& _order;
deba@1750
  1188
      int _num;
deba@1698
  1189
    };
deba@1750
  1190
    
deba@1698
  1191
  }
deba@1698
  1192
deba@2429
  1193
  /// \ingroup graph_prop
deba@1750
  1194
  ///
deba@1750
  1195
  /// \brief Sort the nodes of a DAG into topolgical order.
deba@1750
  1196
  ///
deba@1750
  1197
  /// Sort the nodes of a DAG into topolgical order.
deba@1750
  1198
  ///
deba@1793
  1199
  /// \param graph The graph. It should be directed and acyclic.
deba@1793
  1200
  /// \retval order A writable node map. The values will be set from 0 to
deba@1750
  1201
  /// the number of the nodes in the graph minus one. Each values of the map
deba@1750
  1202
  /// will be set exactly once, the values  will be set descending order.
deba@1750
  1203
  ///
deba@1750
  1204
  /// \see checkedTopologicalSort
deba@1750
  1205
  /// \see dag
deba@1698
  1206
  template <typename Graph, typename NodeMap>
deba@1750
  1207
  void topologicalSort(const Graph& graph, NodeMap& order) {
deba@1750
  1208
    using namespace _topology_bits;
deba@1750
  1209
alpar@2260
  1210
    checkConcept<concepts::Graph, Graph>();
alpar@2260
  1211
    checkConcept<concepts::WriteMap<typename Graph::Node, int>, NodeMap>();
deba@1750
  1212
deba@1750
  1213
    typedef typename Graph::Node Node;
deba@1750
  1214
    typedef typename Graph::NodeIt NodeIt;
deba@1750
  1215
    typedef typename Graph::Edge Edge;
deba@1750
  1216
deba@1750
  1217
    TopologicalSortVisitor<Graph, NodeMap> 
deba@1750
  1218
      visitor(order, countNodes(graph)); 
deba@1750
  1219
deba@1750
  1220
    DfsVisit<Graph, TopologicalSortVisitor<Graph, NodeMap> >
deba@1750
  1221
      dfs(graph, visitor);
deba@1750
  1222
deba@1750
  1223
    dfs.init();
deba@1750
  1224
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
  1225
      if (!dfs.reached(it)) {
deba@1750
  1226
	dfs.addSource(it);
deba@1750
  1227
	dfs.start();
deba@1750
  1228
      }
deba@1750
  1229
    }    
deba@1750
  1230
  }
deba@1750
  1231
deba@2429
  1232
  /// \ingroup graph_prop
deba@1750
  1233
  ///
deba@1750
  1234
  /// \brief Sort the nodes of a DAG into topolgical order.
deba@1750
  1235
  ///
deba@1750
  1236
  /// Sort the nodes of a DAG into topolgical order. It also checks
deba@1750
  1237
  /// that the given graph is DAG.
deba@1750
  1238
  ///
deba@1793
  1239
  /// \param graph The graph. It should be directed and acyclic.
deba@1750
  1240
  /// \retval order A readable - writable node map. The values will be set 
deba@1750
  1241
  /// from 0 to the number of the nodes in the graph minus one. Each values 
deba@1750
  1242
  /// of the map will be set exactly once, the values will be set descending 
deba@1750
  1243
  /// order.
deba@1750
  1244
  /// \return %False when the graph is not DAG.
deba@1750
  1245
  ///
deba@1750
  1246
  /// \see topologicalSort
deba@1750
  1247
  /// \see dag
deba@1750
  1248
  template <typename Graph, typename NodeMap>
deba@1750
  1249
  bool checkedTopologicalSort(const Graph& graph, NodeMap& order) {
deba@1698
  1250
    using namespace _topology_bits;
deba@1698
  1251
alpar@2260
  1252
    checkConcept<concepts::Graph, Graph>();
alpar@2260
  1253
    checkConcept<concepts::ReadWriteMap<typename Graph::Node, int>, NodeMap>();
deba@1698
  1254
deba@1698
  1255
    typedef typename Graph::Node Node;
deba@1698
  1256
    typedef typename Graph::NodeIt NodeIt;
deba@1698
  1257
    typedef typename Graph::Edge Edge;
deba@1698
  1258
deba@1750
  1259
    order = constMap<Node, int, -1>();
deba@1698
  1260
deba@1750
  1261
    TopologicalSortVisitor<Graph, NodeMap> 
deba@1750
  1262
      visitor(order, countNodes(graph)); 
deba@1698
  1263
deba@1750
  1264
    DfsVisit<Graph, TopologicalSortVisitor<Graph, NodeMap> >
deba@1750
  1265
      dfs(graph, visitor);
deba@1698
  1266
deba@1698
  1267
    dfs.init();
deba@1698
  1268
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1698
  1269
      if (!dfs.reached(it)) {
deba@1698
  1270
	dfs.addSource(it);
deba@1698
  1271
	while (!dfs.emptyQueue()) {
deba@1750
  1272
 	  Edge edge = dfs.nextEdge();
deba@1750
  1273
 	  Node target = graph.target(edge);
deba@1750
  1274
 	  if (dfs.reached(target) && order[target] == -1) {
deba@1750
  1275
 	    return false;
deba@1750
  1276
 	  }
deba@1750
  1277
 	  dfs.processNextEdge();
deba@1750
  1278
 	}
deba@1698
  1279
      }
deba@1750
  1280
    }
deba@1698
  1281
    return true;
deba@1698
  1282
  }
deba@1698
  1283
deba@2429
  1284
  /// \ingroup graph_prop
deba@1698
  1285
  ///
deba@1750
  1286
  /// \brief Check that the given directed graph is a DAG.
deba@1750
  1287
  ///
deba@1750
  1288
  /// Check that the given directed graph is a DAG. The DAG is
deba@1698
  1289
  /// an Directed Acyclic Graph.
deba@1750
  1290
  /// \return %False when the graph is not DAG.
deba@1750
  1291
  /// \see acyclic
deba@1698
  1292
  template <typename Graph>
deba@1698
  1293
  bool dag(const Graph& graph) {
deba@1698
  1294
alpar@2260
  1295
    checkConcept<concepts::Graph, Graph>();
deba@1698
  1296
deba@1698
  1297
    typedef typename Graph::Node Node;
deba@1698
  1298
    typedef typename Graph::NodeIt NodeIt;
deba@1698
  1299
    typedef typename Graph::Edge Edge;
deba@1698
  1300
deba@1698
  1301
    typedef typename Graph::template NodeMap<bool> ProcessedMap;
deba@1698
  1302
deba@1698
  1303
    typename Dfs<Graph>::template DefProcessedMap<ProcessedMap>::
deba@1709
  1304
      Create dfs(graph);
deba@1698
  1305
deba@1698
  1306
    ProcessedMap processed(graph);
deba@1698
  1307
    dfs.processedMap(processed);
deba@1698
  1308
deba@1698
  1309
    dfs.init();
deba@1698
  1310
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1698
  1311
      if (!dfs.reached(it)) {
deba@1698
  1312
	dfs.addSource(it);
deba@1698
  1313
	while (!dfs.emptyQueue()) {
deba@1698
  1314
	  Edge edge = dfs.nextEdge();
deba@1698
  1315
	  Node target = graph.target(edge);
deba@1698
  1316
	  if (dfs.reached(target) && !processed[target]) {
deba@1698
  1317
	    return false;
deba@1698
  1318
	  }
deba@1698
  1319
	  dfs.processNextEdge();
deba@1698
  1320
	}
deba@1698
  1321
      }
deba@1698
  1322
    }    
deba@1698
  1323
    return true;
deba@1698
  1324
  }
deba@1698
  1325
deba@2429
  1326
  /// \ingroup graph_prop
deba@1698
  1327
  ///
deba@1698
  1328
  /// \brief Check that the given undirected graph is acyclic.
deba@1698
  1329
  ///
deba@1698
  1330
  /// Check that the given undirected graph acyclic.
deba@1750
  1331
  /// \param graph The undirected graph.
deba@1750
  1332
  /// \return %True when there is no circle in the graph.
deba@1750
  1333
  /// \see dag
klao@1909
  1334
  template <typename UGraph>
klao@1909
  1335
  bool acyclic(const UGraph& graph) {
alpar@2260
  1336
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1337
    typedef typename UGraph::Node Node;
klao@1909
  1338
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1339
    typedef typename UGraph::Edge Edge;
klao@1909
  1340
    Dfs<UGraph> dfs(graph);
deba@1698
  1341
    dfs.init();
deba@1698
  1342
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1698
  1343
      if (!dfs.reached(it)) {
deba@1698
  1344
	dfs.addSource(it);
deba@1698
  1345
	while (!dfs.emptyQueue()) {
deba@1698
  1346
	  Edge edge = dfs.nextEdge();
deba@1698
  1347
	  Node source = graph.source(edge);
deba@1698
  1348
	  Node target = graph.target(edge);
deba@1698
  1349
	  if (dfs.reached(target) && 
deba@1763
  1350
	      dfs.predEdge(source) != graph.oppositeEdge(edge)) {
deba@1698
  1351
	    return false;
deba@1698
  1352
	  }
deba@1698
  1353
	  dfs.processNextEdge();
deba@1698
  1354
	}
deba@1698
  1355
      }
deba@1698
  1356
    }
deba@1698
  1357
    return true;
deba@1698
  1358
  }
deba@1698
  1359
deba@2429
  1360
  /// \ingroup graph_prop
deba@1750
  1361
  ///
deba@1698
  1362
  /// \brief Check that the given undirected graph is tree.
deba@1698
  1363
  ///
deba@1698
  1364
  /// Check that the given undirected graph is tree.
deba@1750
  1365
  /// \param graph The undirected graph.
deba@1750
  1366
  /// \return %True when the graph is acyclic and connected.
klao@1909
  1367
  template <typename UGraph>
klao@1909
  1368
  bool tree(const UGraph& graph) {
alpar@2260
  1369
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1370
    typedef typename UGraph::Node Node;
klao@1909
  1371
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1372
    typedef typename UGraph::Edge Edge;
klao@1909
  1373
    Dfs<UGraph> dfs(graph);
deba@1698
  1374
    dfs.init();
deba@1698
  1375
    dfs.addSource(NodeIt(graph));
deba@1698
  1376
    while (!dfs.emptyQueue()) {
deba@1698
  1377
      Edge edge = dfs.nextEdge();
deba@1698
  1378
      Node source = graph.source(edge);
deba@1698
  1379
      Node target = graph.target(edge);
deba@1698
  1380
      if (dfs.reached(target) && 
deba@1763
  1381
	  dfs.predEdge(source) != graph.oppositeEdge(edge)) {
deba@1698
  1382
	return false;
deba@1698
  1383
      }
deba@1698
  1384
      dfs.processNextEdge();
deba@1698
  1385
    }
deba@1698
  1386
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1698
  1387
      if (!dfs.reached(it)) {
deba@1698
  1388
	return false;
deba@1698
  1389
      }
deba@1698
  1390
    }    
deba@1698
  1391
    return true;
deba@1698
  1392
  }
alpar@1739
  1393
deba@2306
  1394
  namespace _topology_bits {
deba@2306
  1395
deba@2306
  1396
    template <typename Graph>
deba@2306
  1397
    class BipartiteVisitor : public BfsVisitor<Graph> {
deba@2306
  1398
    public:
deba@2306
  1399
      typedef typename Graph::Edge Edge;
deba@2306
  1400
      typedef typename Graph::Node Node;
deba@2306
  1401
deba@2306
  1402
      BipartiteVisitor(const Graph& graph, bool& bipartite) 
deba@2306
  1403
        : _graph(graph), _part(graph), _bipartite(bipartite) {}
deba@2306
  1404
      
deba@2306
  1405
      void start(const Node& node) {
deba@2306
  1406
        _part[node] = true;
deba@2306
  1407
      }
deba@2306
  1408
      void discover(const Edge& edge) {
deba@2306
  1409
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
deba@2306
  1410
      }
deba@2306
  1411
      void examine(const Edge& edge) {
deba@2306
  1412
        _bipartite = _bipartite && 
deba@2306
  1413
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
deba@2306
  1414
      }
deba@2306
  1415
deba@2306
  1416
    private:
deba@2306
  1417
deba@2306
  1418
      const Graph& _graph;
deba@2306
  1419
      typename Graph::template NodeMap<bool> _part;
deba@2306
  1420
      bool& _bipartite;
deba@2306
  1421
    };
deba@2306
  1422
deba@2306
  1423
    template <typename Graph, typename PartMap>
deba@2306
  1424
    class BipartitePartitionsVisitor : public BfsVisitor<Graph> {
deba@2306
  1425
    public:
deba@2306
  1426
      typedef typename Graph::Edge Edge;
deba@2306
  1427
      typedef typename Graph::Node Node;
deba@2306
  1428
deba@2306
  1429
      BipartitePartitionsVisitor(const Graph& graph, 
deba@2306
  1430
                                 PartMap& part, bool& bipartite) 
deba@2306
  1431
        : _graph(graph), _part(part), _bipartite(bipartite) {}
deba@2306
  1432
      
deba@2306
  1433
      void start(const Node& node) {
deba@2306
  1434
        _part.set(node, true);
deba@2306
  1435
      }
deba@2306
  1436
      void discover(const Edge& edge) {
deba@2306
  1437
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
deba@2306
  1438
      }
deba@2306
  1439
      void examine(const Edge& edge) {
deba@2306
  1440
        _bipartite = _bipartite && 
deba@2306
  1441
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
deba@2306
  1442
      }
deba@2306
  1443
deba@2306
  1444
    private:
deba@2306
  1445
deba@2306
  1446
      const Graph& _graph;
deba@2306
  1447
      PartMap& _part;
deba@2306
  1448
      bool& _bipartite;
deba@2306
  1449
    };
deba@2306
  1450
  }
deba@2306
  1451
deba@2429
  1452
  /// \ingroup graph_prop
alpar@1739
  1453
  ///
deba@1800
  1454
  /// \brief Check if the given undirected graph is bipartite or not
deba@1750
  1455
  ///
deba@1800
  1456
  /// The function checks if the given undirected \c graph graph is bipartite 
deba@1800
  1457
  /// or not. The \ref Bfs algorithm is used to calculate the result.
deba@1750
  1458
  /// \param graph The undirected graph.
deba@1800
  1459
  /// \return %True if \c graph is bipartite, %false otherwise.
deba@1800
  1460
  /// \sa bipartitePartitions
deba@1800
  1461
  ///
deba@1800
  1462
  /// \author Balazs Attila Mihaly  
klao@1909
  1463
  template<typename UGraph>
klao@1909
  1464
  inline bool bipartite(const UGraph &graph){
deba@2306
  1465
    using namespace _topology_bits;
deba@2306
  1466
alpar@2260
  1467
    checkConcept<concepts::UGraph, UGraph>();
deba@1800
  1468
    
klao@1909
  1469
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1470
    typedef typename UGraph::EdgeIt EdgeIt;
deba@1800
  1471
    
deba@2306
  1472
    bool bipartite = true;
deba@2306
  1473
deba@2306
  1474
    BipartiteVisitor<UGraph> 
deba@2306
  1475
      visitor(graph, bipartite);
deba@2306
  1476
    BfsVisit<UGraph, BipartiteVisitor<UGraph> > 
deba@2306
  1477
      bfs(graph, visitor);
deba@1800
  1478
    bfs.init();
deba@2306
  1479
    for(NodeIt it(graph); it != INVALID; ++it) {
deba@2306
  1480
      if(!bfs.reached(it)){
deba@2306
  1481
	bfs.addSource(it);
deba@2306
  1482
        while (!bfs.emptyQueue()) {
deba@2306
  1483
          bfs.processNextNode();
deba@2306
  1484
          if (!bipartite) return false;
deba@2306
  1485
        }
deba@1800
  1486
      }
deba@1800
  1487
    }
deba@1800
  1488
    return true;
deba@1979
  1489
  }
deba@1800
  1490
  
deba@2429
  1491
  /// \ingroup graph_prop
deba@1800
  1492
  ///
deba@1800
  1493
  /// \brief Check if the given undirected graph is bipartite or not
deba@1800
  1494
  ///
deba@1800
  1495
  /// The function checks if the given undirected graph is bipartite 
deba@1800
  1496
  /// or not. The  \ref  Bfs  algorithm  is   used  to  calculate the result. 
deba@1800
  1497
  /// During the execution, the \c partMap will be set as the two 
deba@1800
  1498
  /// partitions of the graph.
deba@1800
  1499
  /// \param graph The undirected graph.
alpar@1808
  1500
  /// \retval partMap A writable bool map of nodes. It will be set as the
deba@1800
  1501
  /// two partitions of the graph. 
deba@1800
  1502
  /// \return %True if \c graph is bipartite, %false otherwise.
deba@1800
  1503
  ///
deba@1800
  1504
  /// \author Balazs Attila Mihaly  
deba@1800
  1505
  ///
deba@1800
  1506
  /// \image html bipartite_partitions.png
deba@1800
  1507
  /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
klao@1909
  1508
  template<typename UGraph, typename NodeMap>
klao@1909
  1509
  inline bool bipartitePartitions(const UGraph &graph, NodeMap &partMap){
deba@2306
  1510
    using namespace _topology_bits;
deba@2306
  1511
alpar@2260
  1512
    checkConcept<concepts::UGraph, UGraph>();
deba@1800
  1513
    
klao@1909
  1514
    typedef typename UGraph::Node Node;
klao@1909
  1515
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1516
    typedef typename UGraph::EdgeIt EdgeIt;
deba@2306
  1517
deba@2306
  1518
    bool bipartite = true;
deba@2306
  1519
deba@2306
  1520
    BipartitePartitionsVisitor<UGraph, NodeMap> 
deba@2306
  1521
      visitor(graph, partMap, bipartite);
deba@2306
  1522
    BfsVisit<UGraph, BipartitePartitionsVisitor<UGraph, NodeMap> > 
deba@2306
  1523
      bfs(graph, visitor);
deba@1800
  1524
    bfs.init();
deba@2306
  1525
    for(NodeIt it(graph); it != INVALID; ++it) {
deba@2306
  1526
      if(!bfs.reached(it)){
deba@2306
  1527
	bfs.addSource(it);
deba@2306
  1528
        while (!bfs.emptyQueue()) {
deba@2306
  1529
          bfs.processNextNode();
deba@2306
  1530
          if (!bipartite) return false;
deba@2306
  1531
        }
deba@1740
  1532
      }
deba@1740
  1533
    }
deba@2306
  1534
    return true;
deba@2306
  1535
  }
deba@2306
  1536
deba@2306
  1537
  /// \brief Returns true when there is not loop edge in the graph.
deba@2306
  1538
  ///
deba@2306
  1539
  /// Returns true when there is not loop edge in the graph.
deba@2306
  1540
  template <typename Graph>
deba@2306
  1541
  bool loopFree(const Graph& graph) {
deba@2306
  1542
    for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
deba@2306
  1543
      if (graph.source(it) == graph.target(it)) return false;
deba@2306
  1544
    }
deba@2306
  1545
    return true;
deba@2306
  1546
  }
deba@2306
  1547
deba@2306
  1548
  /// \brief Returns true when there is not parallel edges in the graph.
deba@2306
  1549
  ///
deba@2306
  1550
  /// Returns true when there is not parallel edges in the graph.
deba@2306
  1551
  template <typename Graph>
deba@2306
  1552
  bool parallelFree(const Graph& graph) {
deba@2306
  1553
    typename Graph::template NodeMap<bool> reached(graph, false);
deba@2306
  1554
    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
deba@2306
  1555
      for (typename Graph::OutEdgeIt e(graph, n); e != INVALID; ++e) {
deba@2306
  1556
        if (reached[graph.target(e)]) return false;
deba@2306
  1557
        reached.set(graph.target(e), true);
deba@2306
  1558
      }
deba@2306
  1559
      for (typename Graph::OutEdgeIt e(graph, n); e != INVALID; ++e) {
deba@2306
  1560
        reached.set(graph.target(e), false);
deba@2306
  1561
      }
deba@2306
  1562
    }
deba@2306
  1563
    return true;
deba@2306
  1564
  }
deba@2306
  1565
deba@2306
  1566
  /// \brief Returns true when there is not loop edge and parallel
deba@2306
  1567
  /// edges in the graph.
deba@2306
  1568
  ///
deba@2306
  1569
  /// Returns true when there is not loop edge and parallel edges in
deba@2306
  1570
  /// the graph.
deba@2306
  1571
  template <typename Graph>
deba@2306
  1572
  bool simpleGraph(const Graph& graph) {
deba@2306
  1573
    typename Graph::template NodeMap<bool> reached(graph, false);
deba@2306
  1574
    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
deba@2306
  1575
      reached.set(n, true);
deba@2306
  1576
      for (typename Graph::OutEdgeIt e(graph, n); e != INVALID; ++e) {
deba@2306
  1577
        if (reached[graph.target(e)]) return false;
deba@2306
  1578
        reached.set(graph.target(e), true);
deba@2306
  1579
      }
deba@2306
  1580
      for (typename Graph::OutEdgeIt e(graph, n); e != INVALID; ++e) {
deba@2306
  1581
        reached.set(graph.target(e), false);
deba@2306
  1582
      }
deba@2306
  1583
      reached.set(n, false);
deba@1800
  1584
    }
deba@1750
  1585
    return true;
deba@1979
  1586
  }
deba@1750
  1587
   
deba@1698
  1588
} //namespace lemon
deba@1698
  1589
deba@1698
  1590
#endif //LEMON_TOPOLOGY_H