lemon/topology.h
author alpar
Tue, 24 Oct 2006 17:19:16 +0000
changeset 2260 4274224f8a7d
parent 2111 ea1fa1bc3f6d
child 2306 42cce226b87b
permissions -rw-r--r--
concept -> concepts (namespace & directory)
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@1956
     5
 * Copyright (C) 2003-2006
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@1750
    38
/// \ingroup topology
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@1750
    46
  /// \ingroup topology
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@1750
    69
  /// \ingroup topology
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@1750
   111
  /// \ingroup topology
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@1750
   234
  /// \ingroup topology
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@1750
   290
  /// \ingroup topology
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@1750
   295
  /// The strongly connected components are the classes of an equivalence
deba@1750
   296
  /// relation on the nodes of the graph. Two nodes are connected with
deba@1750
   297
  /// directed paths in both direction.
deba@1750
   298
  ///
deba@1793
   299
  /// \param graph The graph.
deba@1750
   300
  /// \return The number of components
alpar@1807
   301
  /// \note By definition, the empty graph has zero
alpar@1807
   302
  /// strongly connected components.
deba@1750
   303
  template <typename Graph>
deba@1750
   304
  int countStronglyConnectedComponents(const Graph& graph) {
alpar@2260
   305
    checkConcept<concepts::Graph, Graph>();
deba@1750
   306
deba@1750
   307
    using namespace _topology_bits;
deba@1750
   308
deba@1750
   309
    typedef typename Graph::Node Node;
deba@1750
   310
    typedef typename Graph::Edge Edge;
deba@1750
   311
    typedef typename Graph::NodeIt NodeIt;
deba@1750
   312
    typedef typename Graph::EdgeIt EdgeIt;
deba@1750
   313
    
deba@1750
   314
    typedef std::vector<Node> Container;
deba@1750
   315
    typedef typename Container::iterator Iterator;
deba@1750
   316
deba@1750
   317
    Container nodes(countNodes(graph));
deba@1750
   318
    typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
deba@1750
   319
    Visitor visitor(nodes.begin());
deba@1750
   320
      
deba@1750
   321
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@1750
   322
    dfs.init();
deba@1750
   323
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   324
      if (!dfs.reached(it)) {
deba@1750
   325
	dfs.addSource(it);
deba@1750
   326
	dfs.start();
deba@1750
   327
      }
deba@1750
   328
    }
deba@1750
   329
deba@1750
   330
    typedef typename Container::reverse_iterator RIterator;
deba@1750
   331
    typedef RevGraphAdaptor<const Graph> RGraph;
deba@1750
   332
deba@1750
   333
    RGraph rgraph(graph);
deba@1750
   334
deba@1750
   335
    typedef DfsVisitor<Graph> RVisitor;
deba@1750
   336
    RVisitor rvisitor;
deba@1750
   337
deba@1750
   338
    DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
deba@1750
   339
deba@1750
   340
    int compNum = 0;
deba@1750
   341
deba@1750
   342
    rdfs.init();
deba@1750
   343
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@1750
   344
      if (!rdfs.reached(*it)) {
deba@1750
   345
	rdfs.addSource(*it);
deba@1750
   346
	rdfs.start();
deba@1750
   347
	++compNum;
deba@1750
   348
      }
deba@1750
   349
    }
deba@1750
   350
    return compNum;
deba@1750
   351
  }
deba@1750
   352
deba@1750
   353
  /// \ingroup topology
deba@1750
   354
  ///
deba@1750
   355
  /// \brief Find the strongly connected components of a directed graph
deba@1750
   356
  ///
deba@1750
   357
  /// Find the strongly connected components of a directed graph.
deba@1750
   358
  /// The strongly connected components are the classes of an equivalence
deba@1750
   359
  /// relation on the nodes of the graph. Two nodes are in relationship
deba@1750
   360
  /// when there are directed paths between them in both direction.
deba@1750
   361
  ///
deba@1763
   362
  /// \image html strongly_connected_components.png
deba@1763
   363
  /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
deba@1763
   364
  ///
deba@1793
   365
  /// \param graph The graph.
deba@1793
   366
  /// \retval compMap A writable node map. The values will be set from 0 to
deba@1750
   367
  /// the number of the strongly connected components minus one. Each values 
deba@1750
   368
  /// of the map will be set exactly once, the values of a certain component 
deba@1750
   369
  /// will be set continuously.
deba@1750
   370
  /// \return The number of components
deba@1763
   371
  ///
deba@1750
   372
  template <typename Graph, typename NodeMap>
deba@1750
   373
  int stronglyConnectedComponents(const Graph& graph, NodeMap& compMap) {
alpar@2260
   374
    checkConcept<concepts::Graph, Graph>();
deba@1750
   375
    typedef typename Graph::Node Node;
deba@1750
   376
    typedef typename Graph::NodeIt NodeIt;
alpar@2260
   377
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
deba@1750
   378
deba@1750
   379
    using namespace _topology_bits;
deba@1750
   380
    
deba@1750
   381
    typedef std::vector<Node> Container;
deba@1750
   382
    typedef typename Container::iterator Iterator;
deba@1750
   383
deba@1750
   384
    Container nodes(countNodes(graph));
deba@1750
   385
    typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
deba@1750
   386
    Visitor visitor(nodes.begin());
deba@1750
   387
      
deba@1750
   388
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@1750
   389
    dfs.init();
deba@1750
   390
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   391
      if (!dfs.reached(it)) {
deba@1750
   392
	dfs.addSource(it);
deba@1750
   393
	dfs.start();
deba@1750
   394
      }
deba@1750
   395
    }
deba@1750
   396
deba@1750
   397
    typedef typename Container::reverse_iterator RIterator;
deba@1750
   398
    typedef RevGraphAdaptor<const Graph> RGraph;
deba@1750
   399
deba@1750
   400
    RGraph rgraph(graph);
deba@1750
   401
deba@1750
   402
    int compNum = 0;
deba@1750
   403
deba@1750
   404
    typedef FillMapVisitor<RGraph, NodeMap> RVisitor;
deba@1750
   405
    RVisitor rvisitor(compMap, compNum);
deba@1750
   406
deba@1750
   407
    DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
deba@1750
   408
deba@1750
   409
    rdfs.init();
deba@1750
   410
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@1750
   411
      if (!rdfs.reached(*it)) {
deba@1750
   412
	rdfs.addSource(*it);
deba@1750
   413
	rdfs.start();
deba@1750
   414
	++compNum;
deba@1750
   415
      }
deba@1750
   416
    }
deba@1750
   417
    return compNum;
deba@1750
   418
  }
deba@1750
   419
deba@1750
   420
  /// \ingroup topology
deba@1750
   421
  ///
deba@1750
   422
  /// \brief Find the cut edges of the strongly connected components.
deba@1750
   423
  ///
deba@1750
   424
  /// Find the cut edges of the strongly connected components.
deba@1750
   425
  /// The strongly connected components are the classes of an equivalence
deba@1750
   426
  /// relation on the nodes of the graph. Two nodes are in relationship
deba@1750
   427
  /// when there are directed paths between them in both direction.
deba@1750
   428
  /// The strongly connected components are separated by the cut edges.
deba@1750
   429
  ///
deba@1793
   430
  /// \param graph The graph.
deba@1793
   431
  /// \retval cutMap A writable node map. The values will be set true when the
deba@1793
   432
  /// edge is a cut edge.
deba@1750
   433
  ///
deba@1750
   434
  /// \return The number of cut edges
deba@1750
   435
  template <typename Graph, typename EdgeMap>
deba@1750
   436
  int stronglyConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
alpar@2260
   437
    checkConcept<concepts::Graph, Graph>();
deba@1750
   438
    typedef typename Graph::Node Node;
deba@1750
   439
    typedef typename Graph::Edge Edge;
deba@1750
   440
    typedef typename Graph::NodeIt NodeIt;
alpar@2260
   441
    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
deba@1750
   442
deba@1750
   443
    using namespace _topology_bits;
deba@1750
   444
    
deba@1750
   445
    typedef std::vector<Node> Container;
deba@1750
   446
    typedef typename Container::iterator Iterator;
deba@1750
   447
deba@1750
   448
    Container nodes(countNodes(graph));
deba@1750
   449
    typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
deba@1750
   450
    Visitor visitor(nodes.begin());
deba@1750
   451
      
deba@1750
   452
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@1750
   453
    dfs.init();
deba@1750
   454
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   455
      if (!dfs.reached(it)) {
deba@1750
   456
	dfs.addSource(it);
deba@1750
   457
	dfs.start();
deba@1750
   458
      }
deba@1750
   459
    }
deba@1750
   460
deba@1750
   461
    typedef typename Container::reverse_iterator RIterator;
deba@1750
   462
    typedef RevGraphAdaptor<const Graph> RGraph;
deba@1750
   463
deba@1750
   464
    RGraph rgraph(graph);
deba@1750
   465
deba@1750
   466
    int cutNum = 0;
deba@1750
   467
deba@1750
   468
    typedef StronglyConnectedCutEdgesVisitor<RGraph, EdgeMap> RVisitor;
deba@1750
   469
    RVisitor rvisitor(rgraph, cutMap, cutNum);
deba@1750
   470
deba@1750
   471
    DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
deba@1750
   472
deba@1750
   473
    rdfs.init();
deba@1750
   474
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@1750
   475
      if (!rdfs.reached(*it)) {
deba@1750
   476
	rdfs.addSource(*it);
deba@1750
   477
	rdfs.start();
deba@1750
   478
      }
deba@1750
   479
    }
deba@1750
   480
    return cutNum;
deba@1750
   481
  }
deba@1750
   482
deba@1698
   483
  namespace _topology_bits {
deba@1698
   484
    
deba@1750
   485
    template <typename Graph>
deba@1800
   486
    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Graph> {
deba@1698
   487
    public:
deba@1750
   488
      typedef typename Graph::Node Node;
deba@1750
   489
      typedef typename Graph::Edge Edge;
klao@1909
   490
      typedef typename Graph::UEdge UEdge;
deba@1698
   491
deba@1800
   492
      CountBiNodeConnectedComponentsVisitor(const Graph& graph, int &compNum) 
deba@1750
   493
	: _graph(graph), _compNum(compNum), 
deba@1750
   494
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   495
deba@1750
   496
      void start(const Node& node) {
deba@1750
   497
	_predMap.set(node, INVALID);
deba@1750
   498
      }
deba@1750
   499
      
deba@1750
   500
      void reach(const Node& node) {
deba@1750
   501
	_numMap.set(node, _num);
deba@1750
   502
	_retMap.set(node, _num);
deba@1750
   503
	++_num;
deba@1750
   504
      }
deba@1750
   505
deba@1750
   506
      void discover(const Edge& edge) {
deba@1750
   507
	_predMap.set(_graph.target(edge), _graph.source(edge));
deba@1750
   508
      }
deba@1750
   509
deba@1750
   510
      void examine(const Edge& edge) {
deba@1750
   511
	if (_graph.source(edge) == _graph.target(edge) && 
deba@1750
   512
	    _graph.direction(edge)) {
deba@1750
   513
	  ++_compNum;
deba@1750
   514
	  return;
deba@1750
   515
	}
deba@1750
   516
	if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
deba@1750
   517
	  return;
deba@1750
   518
	}
deba@1750
   519
	if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
deba@1750
   520
	  _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
deba@1698
   521
	}
deba@1698
   522
      }
deba@1698
   523
deba@1750
   524
      void backtrack(const Edge& edge) {
deba@1750
   525
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   526
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   527
	}  
deba@1750
   528
	if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
deba@1750
   529
	  ++_compNum;
deba@1750
   530
	}
deba@1750
   531
      }
deba@1750
   532
      
deba@1750
   533
    private:
deba@1750
   534
      const Graph& _graph;
deba@1750
   535
      int& _compNum; 
deba@1750
   536
deba@1750
   537
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   538
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   539
      typename Graph::template NodeMap<Node> _predMap;
deba@1750
   540
      int _num;
deba@1750
   541
    };
deba@1750
   542
deba@1750
   543
    template <typename Graph, typename EdgeMap>
deba@1800
   544
    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Graph> {
deba@1750
   545
    public:
deba@1750
   546
      typedef typename Graph::Node Node;
deba@1750
   547
      typedef typename Graph::Edge Edge;
klao@1909
   548
      typedef typename Graph::UEdge UEdge;
deba@1750
   549
deba@1800
   550
      BiNodeConnectedComponentsVisitor(const Graph& graph, 
deba@1750
   551
				       EdgeMap& compMap, int &compNum) 
deba@1750
   552
	: _graph(graph), _compMap(compMap), _compNum(compNum), 
deba@1750
   553
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   554
deba@1750
   555
      void start(const Node& node) {
deba@1750
   556
	_predMap.set(node, INVALID);
deba@1750
   557
      }
deba@1750
   558
      
deba@1750
   559
      void reach(const Node& node) {
deba@1750
   560
	_numMap.set(node, _num);
deba@1750
   561
	_retMap.set(node, _num);
deba@1750
   562
	++_num;
deba@1750
   563
      }
deba@1750
   564
deba@1750
   565
      void discover(const Edge& edge) {
deba@1750
   566
	Node target = _graph.target(edge);
deba@1750
   567
	_predMap.set(target, edge);
deba@1750
   568
	_edgeStack.push(edge);
deba@1750
   569
      }
deba@1750
   570
deba@1750
   571
      void examine(const Edge& edge) {
deba@1750
   572
	Node source = _graph.source(edge);
deba@1750
   573
	Node target = _graph.target(edge);
deba@1750
   574
	if (source == target && _graph.direction(edge)) {
deba@1750
   575
	  _compMap.set(edge, _compNum);
deba@1750
   576
	  ++_compNum;
deba@1750
   577
	  return;
deba@1750
   578
	}
deba@1750
   579
	if (_numMap[target] < _numMap[source]) {
deba@1750
   580
	  if (_predMap[source] != _graph.oppositeEdge(edge)) {
deba@1750
   581
	    _edgeStack.push(edge);
deba@1750
   582
	  }
deba@1750
   583
	}
deba@1750
   584
	if (_predMap[source] != INVALID && 
deba@1750
   585
	    target == _graph.source(_predMap[source])) {
deba@1750
   586
	  return;
deba@1750
   587
	}
deba@1750
   588
	if (_retMap[source] > _numMap[target]) {
deba@1750
   589
	  _retMap.set(source, _numMap[target]);
deba@1750
   590
	}
deba@1750
   591
      }
deba@1750
   592
deba@1750
   593
      void backtrack(const Edge& edge) {
deba@1750
   594
	Node source = _graph.source(edge);
deba@1750
   595
	Node target = _graph.target(edge);
deba@1750
   596
	if (_retMap[source] > _retMap[target]) {
deba@1750
   597
	  _retMap.set(source, _retMap[target]);
deba@1750
   598
	}  
deba@1750
   599
	if (_numMap[source] <= _retMap[target]) {
deba@1750
   600
	  while (_edgeStack.top() != edge) {
deba@1750
   601
	    _compMap.set(_edgeStack.top(), _compNum);
deba@1750
   602
	    _edgeStack.pop();
deba@1750
   603
	  }
deba@1750
   604
	  _compMap.set(edge, _compNum);
deba@1750
   605
	  _edgeStack.pop();
deba@1750
   606
	  ++_compNum;
deba@1750
   607
	}
deba@1750
   608
      }
deba@1750
   609
      
deba@1750
   610
    private:
deba@1750
   611
      const Graph& _graph;
deba@1750
   612
      EdgeMap& _compMap;
deba@1750
   613
      int& _compNum; 
deba@1750
   614
deba@1750
   615
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   616
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   617
      typename Graph::template NodeMap<Edge> _predMap;
klao@1909
   618
      std::stack<UEdge> _edgeStack;
deba@1750
   619
      int _num;
deba@1750
   620
    };
deba@1750
   621
deba@1750
   622
deba@1750
   623
    template <typename Graph, typename NodeMap>
deba@1800
   624
    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Graph> {
deba@1750
   625
    public:
deba@1750
   626
      typedef typename Graph::Node Node;
deba@1750
   627
      typedef typename Graph::Edge Edge;
klao@1909
   628
      typedef typename Graph::UEdge UEdge;
deba@1750
   629
deba@1800
   630
      BiNodeConnectedCutNodesVisitor(const Graph& graph, NodeMap& cutMap,
deba@1750
   631
				     int& cutNum) 
deba@1750
   632
	: _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
deba@1750
   633
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   634
deba@1750
   635
      void start(const Node& node) {
deba@1750
   636
	_predMap.set(node, INVALID);
deba@1750
   637
	rootCut = false;
deba@1750
   638
      }
deba@1750
   639
      
deba@1750
   640
      void reach(const Node& node) {
deba@1750
   641
	_numMap.set(node, _num);
deba@1750
   642
	_retMap.set(node, _num);
deba@1750
   643
	++_num;
deba@1750
   644
      }
deba@1750
   645
deba@1750
   646
      void discover(const Edge& edge) {
deba@1750
   647
	_predMap.set(_graph.target(edge), _graph.source(edge));
deba@1750
   648
      }
deba@1750
   649
deba@1750
   650
      void examine(const Edge& edge) {
deba@1750
   651
	if (_graph.source(edge) == _graph.target(edge) && 
deba@1750
   652
	    _graph.direction(edge)) {
deba@1750
   653
	  if (!_cutMap[_graph.source(edge)]) {
deba@1750
   654
	    _cutMap.set(_graph.source(edge), true);
deba@1750
   655
	    ++_cutNum;
deba@1750
   656
	  }
deba@1750
   657
	  return;
deba@1750
   658
	}
deba@1750
   659
	if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
deba@1750
   660
	if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
deba@1750
   661
	  _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
deba@1750
   662
	}
deba@1750
   663
      }
deba@1750
   664
deba@1750
   665
      void backtrack(const Edge& edge) {
deba@1750
   666
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   667
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   668
	}  
deba@1750
   669
	if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
deba@1750
   670
	  if (_predMap[_graph.source(edge)] != INVALID) {
deba@1750
   671
	    if (!_cutMap[_graph.source(edge)]) {
deba@1750
   672
	      _cutMap.set(_graph.source(edge), true);
deba@1750
   673
	      ++_cutNum;
deba@1750
   674
	    }
deba@1750
   675
	  } else if (rootCut) {
deba@1750
   676
	    if (!_cutMap[_graph.source(edge)]) {
deba@1750
   677
	      _cutMap.set(_graph.source(edge), true);
deba@1750
   678
	      ++_cutNum;
deba@1750
   679
	    }
deba@1750
   680
	  } else {
deba@1750
   681
	    rootCut = true;
deba@1750
   682
	  }
deba@1750
   683
	}
deba@1750
   684
      }
deba@1750
   685
      
deba@1750
   686
    private:
deba@1750
   687
      const Graph& _graph;
deba@1750
   688
      NodeMap& _cutMap;
deba@1750
   689
      int& _cutNum; 
deba@1750
   690
deba@1750
   691
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   692
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   693
      typename Graph::template NodeMap<Node> _predMap;
klao@1909
   694
      std::stack<UEdge> _edgeStack;
deba@1750
   695
      int _num;
deba@1750
   696
      bool rootCut;
deba@1750
   697
    };
deba@1750
   698
deba@1750
   699
  }
deba@1750
   700
klao@1909
   701
  template <typename UGraph>
klao@1909
   702
  int countBiNodeConnectedComponents(const UGraph& graph);
deba@1750
   703
deba@1750
   704
  /// \ingroup topology
deba@1750
   705
  ///
deba@1767
   706
  /// \brief Checks the graph is bi-node-connected.
deba@1750
   707
  ///
deba@1767
   708
  /// This function checks that the undirected graph is bi-node-connected  
deba@1767
   709
  /// graph. The graph is bi-node-connected if any two undirected edge is 
deba@1750
   710
  /// on same circle.
deba@1750
   711
  ///
deba@1750
   712
  /// \param graph The graph.
deba@1767
   713
  /// \return %True when the graph bi-node-connected.
deba@1750
   714
  /// \todo Make it faster.
klao@1909
   715
  template <typename UGraph>
klao@1909
   716
  bool biNodeConnected(const UGraph& graph) {
deba@1800
   717
    return countBiNodeConnectedComponents(graph) == 1;
deba@1750
   718
  }
deba@1750
   719
deba@1750
   720
  /// \ingroup topology
deba@1750
   721
  ///
deba@1750
   722
  /// \brief Count the biconnected components.
deba@1750
   723
  ///
deba@1767
   724
  /// This function finds the bi-node-connected components in an undirected 
deba@1750
   725
  /// graph. The biconnected components are the classes of an equivalence 
deba@1750
   726
  /// relation on the undirected edges. Two undirected edge is in relationship
deba@1750
   727
  /// when they are on same circle.
deba@1750
   728
  ///
deba@1750
   729
  /// \param graph The graph.
deba@1750
   730
  /// \return The number of components.
klao@1909
   731
  template <typename UGraph>
klao@1909
   732
  int countBiNodeConnectedComponents(const UGraph& graph) {
alpar@2260
   733
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
   734
    typedef typename UGraph::NodeIt NodeIt;
deba@1750
   735
deba@1750
   736
    using namespace _topology_bits;
deba@1750
   737
klao@1909
   738
    typedef CountBiNodeConnectedComponentsVisitor<UGraph> Visitor;
deba@1750
   739
deba@1750
   740
    int compNum = 0;
deba@1750
   741
    Visitor visitor(graph, compNum);
deba@1750
   742
klao@1909
   743
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
   744
    dfs.init();
deba@1750
   745
    
deba@1750
   746
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   747
      if (!dfs.reached(it)) {
deba@1750
   748
	dfs.addSource(it);
deba@1750
   749
	dfs.start();
deba@1750
   750
      }
deba@1750
   751
    }
deba@1750
   752
    return compNum;
deba@1750
   753
  }
deba@1750
   754
deba@1750
   755
  /// \ingroup topology
deba@1750
   756
  ///
deba@1767
   757
  /// \brief Find the bi-node-connected components.
deba@1750
   758
  ///
deba@1767
   759
  /// This function finds the bi-node-connected components in an undirected 
deba@1767
   760
  /// graph. The bi-node-connected components are the classes of an equivalence
deba@1750
   761
  /// relation on the undirected edges. Two undirected edge are in relationship
deba@1750
   762
  /// when they are on same circle.
deba@1750
   763
  ///
deba@1763
   764
  /// \image html node_biconnected_components.png
deba@1767
   765
  /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
deba@1763
   766
  ///
deba@1750
   767
  /// \param graph The graph.
klao@1909
   768
  /// \retval compMap A writable uedge map. The values will be set from 0
deba@1793
   769
  /// to the number of the biconnected components minus one. Each values 
deba@1750
   770
  /// of the map will be set exactly once, the values of a certain component 
deba@1750
   771
  /// will be set continuously.
deba@1750
   772
  /// \return The number of components.
deba@1763
   773
  ///
klao@1909
   774
  template <typename UGraph, typename UEdgeMap>
klao@1909
   775
  int biNodeConnectedComponents(const UGraph& graph, 
klao@1909
   776
				UEdgeMap& compMap) {
alpar@2260
   777
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
   778
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
   779
    typedef typename UGraph::UEdge UEdge;
alpar@2260
   780
    checkConcept<concepts::WriteMap<UEdge, int>, UEdgeMap>();
deba@1750
   781
deba@1750
   782
    using namespace _topology_bits;
deba@1750
   783
klao@1909
   784
    typedef BiNodeConnectedComponentsVisitor<UGraph, UEdgeMap> Visitor;
deba@1750
   785
    
deba@1750
   786
    int compNum = 0;
deba@1750
   787
    Visitor visitor(graph, compMap, compNum);
deba@1750
   788
klao@1909
   789
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
   790
    dfs.init();
deba@1750
   791
    
deba@1750
   792
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   793
      if (!dfs.reached(it)) {
deba@1750
   794
	dfs.addSource(it);
deba@1750
   795
	dfs.start();
deba@1750
   796
      }
deba@1750
   797
    }
deba@1750
   798
    return compNum;
deba@1750
   799
  }
deba@1750
   800
deba@1750
   801
  /// \ingroup topology
deba@1750
   802
  ///
deba@1767
   803
  /// \brief Find the bi-node-connected cut nodes.
deba@1750
   804
  ///
deba@1767
   805
  /// This function finds the bi-node-connected cut nodes in an undirected 
deba@1767
   806
  /// graph. The bi-node-connected components are the classes of an equivalence
deba@1750
   807
  /// relation on the undirected edges. Two undirected edges are in 
deba@1750
   808
  /// relationship when they are on same circle. The biconnected components 
deba@1750
   809
  /// are separted by nodes which are the cut nodes of the components.
deba@1750
   810
  ///
deba@1750
   811
  /// \param graph The graph.
deba@1793
   812
  /// \retval cutMap A writable edge map. The values will be set true when
deba@1750
   813
  /// the node separate two or more components.
deba@1750
   814
  /// \return The number of the cut nodes.
klao@1909
   815
  template <typename UGraph, typename NodeMap>
klao@1909
   816
  int biNodeConnectedCutNodes(const UGraph& graph, NodeMap& cutMap) {
alpar@2260
   817
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
   818
    typedef typename UGraph::Node Node;
klao@1909
   819
    typedef typename UGraph::NodeIt NodeIt;
alpar@2260
   820
    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
deba@1750
   821
deba@1750
   822
    using namespace _topology_bits;
deba@1750
   823
klao@1909
   824
    typedef BiNodeConnectedCutNodesVisitor<UGraph, NodeMap> Visitor;
deba@1750
   825
    
deba@1750
   826
    int cutNum = 0;
deba@1750
   827
    Visitor visitor(graph, cutMap, cutNum);
deba@1750
   828
klao@1909
   829
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
   830
    dfs.init();
deba@1750
   831
    
deba@1750
   832
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
   833
      if (!dfs.reached(it)) {
deba@1750
   834
	dfs.addSource(it);
deba@1750
   835
	dfs.start();
deba@1750
   836
      }
deba@1750
   837
    }
deba@1750
   838
    return cutNum;
deba@1750
   839
  }
deba@1750
   840
deba@1750
   841
  namespace _topology_bits {
deba@1750
   842
    
deba@1750
   843
    template <typename Graph>
deba@1800
   844
    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Graph> {
deba@1750
   845
    public:
deba@1750
   846
      typedef typename Graph::Node Node;
deba@1750
   847
      typedef typename Graph::Edge Edge;
klao@1909
   848
      typedef typename Graph::UEdge UEdge;
deba@1750
   849
deba@1800
   850
      CountBiEdgeConnectedComponentsVisitor(const Graph& graph, int &compNum) 
deba@1750
   851
	: _graph(graph), _compNum(compNum), 
deba@1750
   852
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   853
deba@1750
   854
      void start(const Node& node) {
deba@1750
   855
	_predMap.set(node, INVALID);
deba@1750
   856
      }
deba@1750
   857
      
deba@1750
   858
      void reach(const Node& node) {
deba@1750
   859
	_numMap.set(node, _num);
deba@1750
   860
	_retMap.set(node, _num);
deba@1750
   861
	++_num;
deba@1750
   862
      }
deba@1750
   863
      
deba@1750
   864
      void leave(const Node& node) {
deba@1750
   865
	if (_numMap[node] <= _retMap[node]) {
deba@1750
   866
	  ++_compNum;
deba@1750
   867
	}	
deba@1750
   868
      }
deba@1750
   869
deba@1750
   870
      void discover(const Edge& edge) {
deba@1750
   871
	_predMap.set(_graph.target(edge), edge);
deba@1750
   872
      }
deba@1750
   873
deba@1750
   874
      void examine(const Edge& edge) {
deba@1750
   875
	if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
deba@1750
   876
	  return;
deba@1750
   877
	}
deba@1750
   878
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   879
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   880
	}
deba@1750
   881
      }
deba@1750
   882
deba@1750
   883
      void backtrack(const Edge& edge) {
deba@1750
   884
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   885
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   886
	}  
deba@1750
   887
      }
deba@1750
   888
      
deba@1750
   889
    private:
deba@1750
   890
      const Graph& _graph;
deba@1750
   891
      int& _compNum; 
deba@1750
   892
deba@1750
   893
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   894
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   895
      typename Graph::template NodeMap<Edge> _predMap;
deba@1750
   896
      int _num;
deba@1750
   897
    };
deba@1750
   898
deba@1750
   899
    template <typename Graph, typename NodeMap>
deba@1800
   900
    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Graph> {
deba@1750
   901
    public:
deba@1750
   902
      typedef typename Graph::Node Node;
deba@1750
   903
      typedef typename Graph::Edge Edge;
klao@1909
   904
      typedef typename Graph::UEdge UEdge;
deba@1750
   905
deba@1800
   906
      BiEdgeConnectedComponentsVisitor(const Graph& graph, 
deba@1750
   907
				       NodeMap& compMap, int &compNum) 
deba@1750
   908
	: _graph(graph), _compMap(compMap), _compNum(compNum), 
deba@1750
   909
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   910
deba@1750
   911
      void start(const Node& node) {
deba@1750
   912
	_predMap.set(node, INVALID);
deba@1750
   913
      }
deba@1750
   914
      
deba@1750
   915
      void reach(const Node& node) {
deba@1750
   916
	_numMap.set(node, _num);
deba@1750
   917
	_retMap.set(node, _num);
deba@1750
   918
	_nodeStack.push(node);
deba@1750
   919
	++_num;
deba@1750
   920
      }
deba@1750
   921
      
deba@1750
   922
      void leave(const Node& node) {
deba@1750
   923
	if (_numMap[node] <= _retMap[node]) {
deba@1750
   924
	  while (_nodeStack.top() != node) {
deba@1750
   925
	    _compMap.set(_nodeStack.top(), _compNum);
deba@1750
   926
	    _nodeStack.pop();
deba@1750
   927
	  }
deba@1750
   928
	  _compMap.set(node, _compNum);
deba@1750
   929
	  _nodeStack.pop();
deba@1750
   930
	  ++_compNum;
deba@1750
   931
	}	
deba@1750
   932
      }
deba@1750
   933
deba@1750
   934
      void discover(const Edge& edge) {
deba@1750
   935
	_predMap.set(_graph.target(edge), edge);
deba@1750
   936
      }
deba@1750
   937
deba@1750
   938
      void examine(const Edge& edge) {
deba@1750
   939
	if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
deba@1750
   940
	  return;
deba@1750
   941
	}
deba@1750
   942
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   943
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   944
	}
deba@1750
   945
      }
deba@1750
   946
deba@1750
   947
      void backtrack(const Edge& edge) {
deba@1750
   948
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
   949
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
   950
	}  
deba@1750
   951
      }
deba@1750
   952
      
deba@1750
   953
    private:
deba@1750
   954
      const Graph& _graph;
deba@1750
   955
      NodeMap& _compMap;
deba@1750
   956
      int& _compNum; 
deba@1750
   957
deba@1750
   958
      typename Graph::template NodeMap<int> _numMap;
deba@1750
   959
      typename Graph::template NodeMap<int> _retMap;
deba@1750
   960
      typename Graph::template NodeMap<Edge> _predMap;
deba@1750
   961
      std::stack<Node> _nodeStack;
deba@1750
   962
      int _num;
deba@1750
   963
    };
deba@1750
   964
deba@1750
   965
deba@1750
   966
    template <typename Graph, typename EdgeMap>
deba@1800
   967
    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Graph> {
deba@1750
   968
    public:
deba@1750
   969
      typedef typename Graph::Node Node;
deba@1750
   970
      typedef typename Graph::Edge Edge;
klao@1909
   971
      typedef typename Graph::UEdge UEdge;
deba@1750
   972
deba@1800
   973
      BiEdgeConnectedCutEdgesVisitor(const Graph& graph, 
deba@1750
   974
				     EdgeMap& cutMap, int &cutNum) 
deba@1750
   975
	: _graph(graph), _cutMap(cutMap), _cutNum(cutNum), 
deba@1750
   976
	  _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@1750
   977
deba@1750
   978
      void start(const Node& node) {
deba@1750
   979
	_predMap[node] = INVALID;
deba@1750
   980
      }
deba@1750
   981
      
deba@1750
   982
      void reach(const Node& node) {
deba@1750
   983
	_numMap.set(node, _num);
deba@1750
   984
	_retMap.set(node, _num);
deba@1750
   985
	++_num;
deba@1750
   986
      }
deba@1750
   987
      
deba@1750
   988
      void leave(const Node& node) {
deba@1750
   989
	if (_numMap[node] <= _retMap[node]) {
deba@1750
   990
	  if (_predMap[node] != INVALID) {
deba@1750
   991
	    _cutMap.set(_predMap[node], true);
deba@1750
   992
	    ++_cutNum;
deba@1750
   993
	  }
deba@1750
   994
	}	
deba@1750
   995
      }
deba@1750
   996
deba@1750
   997
      void discover(const Edge& edge) {
deba@1750
   998
	_predMap.set(_graph.target(edge), edge);
deba@1750
   999
      }
deba@1750
  1000
deba@1750
  1001
      void examine(const Edge& edge) {
deba@1750
  1002
	if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
deba@1750
  1003
	  return;
deba@1750
  1004
	}
deba@1750
  1005
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
  1006
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
  1007
	}
deba@1750
  1008
      }
deba@1750
  1009
deba@1750
  1010
      void backtrack(const Edge& edge) {
deba@1750
  1011
	if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@1750
  1012
	  _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@1750
  1013
	}  
deba@1750
  1014
      }
deba@1750
  1015
      
deba@1750
  1016
    private:
deba@1750
  1017
      const Graph& _graph;
deba@1750
  1018
      EdgeMap& _cutMap;
deba@1750
  1019
      int& _cutNum; 
deba@1750
  1020
deba@1750
  1021
      typename Graph::template NodeMap<int> _numMap;
deba@1750
  1022
      typename Graph::template NodeMap<int> _retMap;
deba@1750
  1023
      typename Graph::template NodeMap<Edge> _predMap;
deba@1750
  1024
      int _num;
deba@1750
  1025
    };
deba@1750
  1026
  }
deba@1750
  1027
klao@1909
  1028
  template <typename UGraph>
klao@1909
  1029
  int countbiEdgeConnectedComponents(const UGraph& graph);
deba@1750
  1030
deba@1750
  1031
  /// \ingroup topology
deba@1750
  1032
  ///
deba@1767
  1033
  /// \brief Checks that the graph is bi-edge-connected.
deba@1750
  1034
  ///
deba@1767
  1035
  /// This function checks that the graph is bi-edge-connected. The undirected
deba@1767
  1036
  /// graph is bi-edge-connected when any two nodes are connected with two
deba@1750
  1037
  /// edge-disjoint paths.
deba@1750
  1038
  ///
deba@1750
  1039
  /// \param graph The undirected graph.
deba@1750
  1040
  /// \return The number of components.
deba@1750
  1041
  /// \todo Make it faster.
klao@1909
  1042
  template <typename UGraph>
klao@1909
  1043
  bool biEdgeConnected(const UGraph& graph) { 
deba@1800
  1044
    return countBiEdgeConnectedComponents(graph) == 1;
deba@1750
  1045
  }
deba@1750
  1046
deba@1750
  1047
  /// \ingroup topology
deba@1750
  1048
  ///
deba@1767
  1049
  /// \brief Count the bi-edge-connected components.
deba@1750
  1050
  ///
deba@1767
  1051
  /// This function count the bi-edge-connected components in an undirected 
deba@1767
  1052
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@1750
  1053
  /// relation on the nodes. Two nodes are in relationship when they are  
deba@1750
  1054
  /// connected with at least two edge-disjoint paths.
deba@1750
  1055
  ///
deba@1750
  1056
  /// \param graph The undirected graph.
deba@1750
  1057
  /// \return The number of components.
klao@1909
  1058
  template <typename UGraph>
klao@1909
  1059
  int countBiEdgeConnectedComponents(const UGraph& graph) { 
alpar@2260
  1060
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1061
    typedef typename UGraph::NodeIt NodeIt;
deba@1750
  1062
deba@1750
  1063
    using namespace _topology_bits;
deba@1750
  1064
klao@1909
  1065
    typedef CountBiEdgeConnectedComponentsVisitor<UGraph> Visitor;
deba@1750
  1066
    
deba@1750
  1067
    int compNum = 0;
deba@1750
  1068
    Visitor visitor(graph, compNum);
deba@1750
  1069
klao@1909
  1070
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
  1071
    dfs.init();
deba@1750
  1072
    
deba@1750
  1073
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
  1074
      if (!dfs.reached(it)) {
deba@1750
  1075
	dfs.addSource(it);
deba@1750
  1076
	dfs.start();
deba@1750
  1077
      }
deba@1750
  1078
    }
deba@1750
  1079
    return compNum;
deba@1750
  1080
  }
deba@1750
  1081
deba@1750
  1082
  /// \ingroup topology
deba@1750
  1083
  ///
deba@1767
  1084
  /// \brief Find the bi-edge-connected components.
deba@1750
  1085
  ///
deba@1767
  1086
  /// This function finds the bi-edge-connected components in an undirected 
deba@1767
  1087
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@1750
  1088
  /// relation on the nodes. Two nodes are in relationship when they are  
deba@1750
  1089
  /// connected at least two edge-disjoint paths.
deba@1750
  1090
  ///
deba@1763
  1091
  /// \image html edge_biconnected_components.png
deba@1767
  1092
  /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
deba@1763
  1093
  ///
deba@1750
  1094
  /// \param graph The graph.
deba@1793
  1095
  /// \retval compMap A writable node map. The values will be set from 0 to
deba@1750
  1096
  /// the number of the biconnected components minus one. Each values 
deba@1750
  1097
  /// of the map will be set exactly once, the values of a certain component 
deba@1750
  1098
  /// will be set continuously.
deba@1750
  1099
  /// \return The number of components.
deba@1763
  1100
  ///
klao@1909
  1101
  template <typename UGraph, typename NodeMap>
klao@1909
  1102
  int biEdgeConnectedComponents(const UGraph& graph, NodeMap& compMap) { 
alpar@2260
  1103
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1104
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1105
    typedef typename UGraph::Node Node;
alpar@2260
  1106
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
deba@1750
  1107
deba@1750
  1108
    using namespace _topology_bits;
deba@1750
  1109
klao@1909
  1110
    typedef BiEdgeConnectedComponentsVisitor<UGraph, NodeMap> Visitor;
deba@1750
  1111
    
deba@1750
  1112
    int compNum = 0;
deba@1750
  1113
    Visitor visitor(graph, compMap, compNum);
deba@1750
  1114
klao@1909
  1115
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
  1116
    dfs.init();
deba@1750
  1117
    
deba@1750
  1118
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
  1119
      if (!dfs.reached(it)) {
deba@1750
  1120
	dfs.addSource(it);
deba@1750
  1121
	dfs.start();
deba@1750
  1122
      }
deba@1750
  1123
    }
deba@1750
  1124
    return compNum;
deba@1750
  1125
  }
deba@1750
  1126
deba@1750
  1127
  /// \ingroup topology
deba@1750
  1128
  ///
deba@1767
  1129
  /// \brief Find the bi-edge-connected cut edges.
deba@1750
  1130
  ///
deba@1767
  1131
  /// This function finds the bi-edge-connected components in an undirected 
deba@1767
  1132
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@1750
  1133
  /// relation on the nodes. Two nodes are in relationship when they are 
deba@1767
  1134
  /// connected with at least two edge-disjoint paths. The bi-edge-connected 
deba@1750
  1135
  /// components are separted by edges which are the cut edges of the 
deba@1750
  1136
  /// components.
deba@1750
  1137
  ///
deba@1750
  1138
  /// \param graph The graph.
deba@1793
  1139
  /// \retval cutMap A writable node map. The values will be set true when the
deba@1750
  1140
  /// edge is a cut edge.
deba@1750
  1141
  /// \return The number of cut edges.
klao@1909
  1142
  template <typename UGraph, typename UEdgeMap>
klao@1909
  1143
  int biEdgeConnectedCutEdges(const UGraph& graph, UEdgeMap& cutMap) { 
alpar@2260
  1144
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1145
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1146
    typedef typename UGraph::UEdge UEdge;
alpar@2260
  1147
    checkConcept<concepts::WriteMap<UEdge, bool>, UEdgeMap>();
deba@1750
  1148
deba@1750
  1149
    using namespace _topology_bits;
deba@1750
  1150
klao@1909
  1151
    typedef BiEdgeConnectedCutEdgesVisitor<UGraph, UEdgeMap> Visitor;
deba@1750
  1152
    
deba@1750
  1153
    int cutNum = 0;
deba@1750
  1154
    Visitor visitor(graph, cutMap, cutNum);
deba@1750
  1155
klao@1909
  1156
    DfsVisit<UGraph, Visitor> dfs(graph, visitor);
deba@1750
  1157
    dfs.init();
deba@1750
  1158
    
deba@1750
  1159
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
  1160
      if (!dfs.reached(it)) {
deba@1750
  1161
	dfs.addSource(it);
deba@1750
  1162
	dfs.start();
deba@1750
  1163
      }
deba@1750
  1164
    }
deba@1750
  1165
    return cutNum;
deba@1750
  1166
  }
deba@1750
  1167
deba@1750
  1168
deba@1750
  1169
  namespace _topology_bits {
deba@1750
  1170
    
deba@1750
  1171
    template <typename Graph, typename IntNodeMap>
deba@1750
  1172
    class TopologicalSortVisitor : public DfsVisitor<Graph> {
deba@1750
  1173
    public:
deba@1750
  1174
      typedef typename Graph::Node Node;
deba@1750
  1175
      typedef typename Graph::Edge edge;
deba@1750
  1176
deba@1750
  1177
      TopologicalSortVisitor(IntNodeMap& order, int num) 
deba@1750
  1178
	: _order(order), _num(num) {}
deba@1750
  1179
      
deba@1750
  1180
      void leave(const Node& node) {
deba@1750
  1181
	_order.set(node, --_num);
deba@1698
  1182
      }
deba@1698
  1183
deba@1698
  1184
    private:
deba@1750
  1185
      IntNodeMap& _order;
deba@1750
  1186
      int _num;
deba@1698
  1187
    };
deba@1750
  1188
    
deba@1698
  1189
  }
deba@1698
  1190
deba@1750
  1191
  /// \ingroup topology
deba@1750
  1192
  ///
deba@1750
  1193
  /// \brief Sort the nodes of a DAG into topolgical order.
deba@1750
  1194
  ///
deba@1750
  1195
  /// Sort the nodes of a DAG into topolgical order.
deba@1750
  1196
  ///
deba@1793
  1197
  /// \param graph The graph. It should be directed and acyclic.
deba@1793
  1198
  /// \retval order A writable node map. The values will be set from 0 to
deba@1750
  1199
  /// the number of the nodes in the graph minus one. Each values of the map
deba@1750
  1200
  /// will be set exactly once, the values  will be set descending order.
deba@1750
  1201
  ///
deba@1750
  1202
  /// \see checkedTopologicalSort
deba@1750
  1203
  /// \see dag
deba@1698
  1204
  template <typename Graph, typename NodeMap>
deba@1750
  1205
  void topologicalSort(const Graph& graph, NodeMap& order) {
deba@1750
  1206
    using namespace _topology_bits;
deba@1750
  1207
alpar@2260
  1208
    checkConcept<concepts::Graph, Graph>();
alpar@2260
  1209
    checkConcept<concepts::WriteMap<typename Graph::Node, int>, NodeMap>();
deba@1750
  1210
deba@1750
  1211
    typedef typename Graph::Node Node;
deba@1750
  1212
    typedef typename Graph::NodeIt NodeIt;
deba@1750
  1213
    typedef typename Graph::Edge Edge;
deba@1750
  1214
deba@1750
  1215
    TopologicalSortVisitor<Graph, NodeMap> 
deba@1750
  1216
      visitor(order, countNodes(graph)); 
deba@1750
  1217
deba@1750
  1218
    DfsVisit<Graph, TopologicalSortVisitor<Graph, NodeMap> >
deba@1750
  1219
      dfs(graph, visitor);
deba@1750
  1220
deba@1750
  1221
    dfs.init();
deba@1750
  1222
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1750
  1223
      if (!dfs.reached(it)) {
deba@1750
  1224
	dfs.addSource(it);
deba@1750
  1225
	dfs.start();
deba@1750
  1226
      }
deba@1750
  1227
    }    
deba@1750
  1228
  }
deba@1750
  1229
deba@1750
  1230
  /// \ingroup topology
deba@1750
  1231
  ///
deba@1750
  1232
  /// \brief Sort the nodes of a DAG into topolgical order.
deba@1750
  1233
  ///
deba@1750
  1234
  /// Sort the nodes of a DAG into topolgical order. It also checks
deba@1750
  1235
  /// that the given graph is DAG.
deba@1750
  1236
  ///
deba@1793
  1237
  /// \param graph The graph. It should be directed and acyclic.
deba@1750
  1238
  /// \retval order A readable - writable node map. The values will be set 
deba@1750
  1239
  /// from 0 to the number of the nodes in the graph minus one. Each values 
deba@1750
  1240
  /// of the map will be set exactly once, the values will be set descending 
deba@1750
  1241
  /// order.
deba@1750
  1242
  /// \return %False when the graph is not DAG.
deba@1750
  1243
  ///
deba@1750
  1244
  /// \see topologicalSort
deba@1750
  1245
  /// \see dag
deba@1750
  1246
  template <typename Graph, typename NodeMap>
deba@1750
  1247
  bool checkedTopologicalSort(const Graph& graph, NodeMap& order) {
deba@1698
  1248
    using namespace _topology_bits;
deba@1698
  1249
alpar@2260
  1250
    checkConcept<concepts::Graph, Graph>();
alpar@2260
  1251
    checkConcept<concepts::ReadWriteMap<typename Graph::Node, int>, NodeMap>();
deba@1698
  1252
deba@1698
  1253
    typedef typename Graph::Node Node;
deba@1698
  1254
    typedef typename Graph::NodeIt NodeIt;
deba@1698
  1255
    typedef typename Graph::Edge Edge;
deba@1698
  1256
deba@1750
  1257
    order = constMap<Node, int, -1>();
deba@1698
  1258
deba@1750
  1259
    TopologicalSortVisitor<Graph, NodeMap> 
deba@1750
  1260
      visitor(order, countNodes(graph)); 
deba@1698
  1261
deba@1750
  1262
    DfsVisit<Graph, TopologicalSortVisitor<Graph, NodeMap> >
deba@1750
  1263
      dfs(graph, visitor);
deba@1698
  1264
deba@1698
  1265
    dfs.init();
deba@1698
  1266
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1698
  1267
      if (!dfs.reached(it)) {
deba@1698
  1268
	dfs.addSource(it);
deba@1698
  1269
	while (!dfs.emptyQueue()) {
deba@1750
  1270
 	  Edge edge = dfs.nextEdge();
deba@1750
  1271
 	  Node target = graph.target(edge);
deba@1750
  1272
 	  if (dfs.reached(target) && order[target] == -1) {
deba@1750
  1273
 	    return false;
deba@1750
  1274
 	  }
deba@1750
  1275
 	  dfs.processNextEdge();
deba@1750
  1276
 	}
deba@1698
  1277
      }
deba@1750
  1278
    }
deba@1698
  1279
    return true;
deba@1698
  1280
  }
deba@1698
  1281
deba@1750
  1282
  /// \ingroup topology
deba@1698
  1283
  ///
deba@1750
  1284
  /// \brief Check that the given directed graph is a DAG.
deba@1750
  1285
  ///
deba@1750
  1286
  /// Check that the given directed graph is a DAG. The DAG is
deba@1698
  1287
  /// an Directed Acyclic Graph.
deba@1750
  1288
  /// \return %False when the graph is not DAG.
deba@1750
  1289
  /// \see acyclic
deba@1698
  1290
  template <typename Graph>
deba@1698
  1291
  bool dag(const Graph& graph) {
deba@1698
  1292
alpar@2260
  1293
    checkConcept<concepts::Graph, Graph>();
deba@1698
  1294
deba@1698
  1295
    typedef typename Graph::Node Node;
deba@1698
  1296
    typedef typename Graph::NodeIt NodeIt;
deba@1698
  1297
    typedef typename Graph::Edge Edge;
deba@1698
  1298
deba@1698
  1299
    typedef typename Graph::template NodeMap<bool> ProcessedMap;
deba@1698
  1300
deba@1698
  1301
    typename Dfs<Graph>::template DefProcessedMap<ProcessedMap>::
deba@1709
  1302
      Create dfs(graph);
deba@1698
  1303
deba@1698
  1304
    ProcessedMap processed(graph);
deba@1698
  1305
    dfs.processedMap(processed);
deba@1698
  1306
deba@1698
  1307
    dfs.init();
deba@1698
  1308
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1698
  1309
      if (!dfs.reached(it)) {
deba@1698
  1310
	dfs.addSource(it);
deba@1698
  1311
	while (!dfs.emptyQueue()) {
deba@1698
  1312
	  Edge edge = dfs.nextEdge();
deba@1698
  1313
	  Node target = graph.target(edge);
deba@1698
  1314
	  if (dfs.reached(target) && !processed[target]) {
deba@1698
  1315
	    return false;
deba@1698
  1316
	  }
deba@1698
  1317
	  dfs.processNextEdge();
deba@1698
  1318
	}
deba@1698
  1319
      }
deba@1698
  1320
    }    
deba@1698
  1321
    return true;
deba@1698
  1322
  }
deba@1698
  1323
deba@1750
  1324
  /// \ingroup topology
deba@1698
  1325
  ///
deba@1698
  1326
  /// \brief Check that the given undirected graph is acyclic.
deba@1698
  1327
  ///
deba@1698
  1328
  /// Check that the given undirected graph acyclic.
deba@1750
  1329
  /// \param graph The undirected graph.
deba@1750
  1330
  /// \return %True when there is no circle in the graph.
deba@1750
  1331
  /// \see dag
klao@1909
  1332
  template <typename UGraph>
klao@1909
  1333
  bool acyclic(const UGraph& graph) {
alpar@2260
  1334
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1335
    typedef typename UGraph::Node Node;
klao@1909
  1336
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1337
    typedef typename UGraph::Edge Edge;
klao@1909
  1338
    Dfs<UGraph> dfs(graph);
deba@1698
  1339
    dfs.init();
deba@1698
  1340
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1698
  1341
      if (!dfs.reached(it)) {
deba@1698
  1342
	dfs.addSource(it);
deba@1698
  1343
	while (!dfs.emptyQueue()) {
deba@1698
  1344
	  Edge edge = dfs.nextEdge();
deba@1698
  1345
	  Node source = graph.source(edge);
deba@1698
  1346
	  Node target = graph.target(edge);
deba@1698
  1347
	  if (dfs.reached(target) && 
deba@1763
  1348
	      dfs.predEdge(source) != graph.oppositeEdge(edge)) {
deba@1698
  1349
	    return false;
deba@1698
  1350
	  }
deba@1698
  1351
	  dfs.processNextEdge();
deba@1698
  1352
	}
deba@1698
  1353
      }
deba@1698
  1354
    }
deba@1698
  1355
    return true;
deba@1698
  1356
  }
deba@1698
  1357
deba@1750
  1358
  /// \ingroup topology
deba@1750
  1359
  ///
deba@1698
  1360
  /// \brief Check that the given undirected graph is tree.
deba@1698
  1361
  ///
deba@1698
  1362
  /// Check that the given undirected graph is tree.
deba@1750
  1363
  /// \param graph The undirected graph.
deba@1750
  1364
  /// \return %True when the graph is acyclic and connected.
klao@1909
  1365
  template <typename UGraph>
klao@1909
  1366
  bool tree(const UGraph& graph) {
alpar@2260
  1367
    checkConcept<concepts::UGraph, UGraph>();
klao@1909
  1368
    typedef typename UGraph::Node Node;
klao@1909
  1369
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1370
    typedef typename UGraph::Edge Edge;
klao@1909
  1371
    Dfs<UGraph> dfs(graph);
deba@1698
  1372
    dfs.init();
deba@1698
  1373
    dfs.addSource(NodeIt(graph));
deba@1698
  1374
    while (!dfs.emptyQueue()) {
deba@1698
  1375
      Edge edge = dfs.nextEdge();
deba@1698
  1376
      Node source = graph.source(edge);
deba@1698
  1377
      Node target = graph.target(edge);
deba@1698
  1378
      if (dfs.reached(target) && 
deba@1763
  1379
	  dfs.predEdge(source) != graph.oppositeEdge(edge)) {
deba@1698
  1380
	return false;
deba@1698
  1381
      }
deba@1698
  1382
      dfs.processNextEdge();
deba@1698
  1383
    }
deba@1698
  1384
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@1698
  1385
      if (!dfs.reached(it)) {
deba@1698
  1386
	return false;
deba@1698
  1387
      }
deba@1698
  1388
    }    
deba@1698
  1389
    return true;
deba@1698
  1390
  }
alpar@1739
  1391
deba@1750
  1392
  /// \ingroup topology
alpar@1739
  1393
  ///
deba@1800
  1394
  /// \brief Check if the given undirected graph is bipartite or not
deba@1750
  1395
  ///
deba@1800
  1396
  /// The function checks if the given undirected \c graph graph is bipartite 
deba@1800
  1397
  /// or not. The \ref Bfs algorithm is used to calculate the result.
deba@1750
  1398
  /// \param graph The undirected graph.
deba@1800
  1399
  /// \return %True if \c graph is bipartite, %false otherwise.
deba@1800
  1400
  /// \sa bipartitePartitions
deba@1800
  1401
  ///
deba@1800
  1402
  /// \author Balazs Attila Mihaly  
klao@1909
  1403
  template<typename UGraph>
klao@1909
  1404
  inline bool bipartite(const UGraph &graph){
alpar@2260
  1405
    checkConcept<concepts::UGraph, UGraph>();
deba@1800
  1406
    
klao@1909
  1407
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1408
    typedef typename UGraph::EdgeIt EdgeIt;
deba@1800
  1409
    
klao@1909
  1410
    Bfs<UGraph> bfs(graph);
deba@1800
  1411
    bfs.init();
deba@1800
  1412
    for(NodeIt i(graph);i!=INVALID;++i){
deba@1800
  1413
      if(!bfs.reached(i)){
deba@1800
  1414
	bfs.run(i);
deba@1800
  1415
      }
deba@1800
  1416
    }
deba@1800
  1417
    for(EdgeIt i(graph);i!=INVALID;++i){
deba@1800
  1418
      if(bfs.dist(graph.source(i))==bfs.dist(graph.target(i)))return false;
deba@1800
  1419
    }
deba@1800
  1420
    return true;
deba@1979
  1421
  }
deba@1800
  1422
  
deba@1800
  1423
  /// \ingroup topology
deba@1800
  1424
  ///
deba@1800
  1425
  /// \brief Check if the given undirected graph is bipartite or not
deba@1800
  1426
  ///
deba@1800
  1427
  /// The function checks if the given undirected graph is bipartite 
deba@1800
  1428
  /// or not. The  \ref  Bfs  algorithm  is   used  to  calculate the result. 
deba@1800
  1429
  /// During the execution, the \c partMap will be set as the two 
deba@1800
  1430
  /// partitions of the graph.
deba@1800
  1431
  /// \param graph The undirected graph.
alpar@1808
  1432
  /// \retval partMap A writable bool map of nodes. It will be set as the
deba@1800
  1433
  /// two partitions of the graph. 
deba@1800
  1434
  /// \return %True if \c graph is bipartite, %false otherwise.
deba@1800
  1435
  ///
deba@1800
  1436
  /// \author Balazs Attila Mihaly  
deba@1800
  1437
  ///
deba@1800
  1438
  /// \image html bipartite_partitions.png
deba@1800
  1439
  /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
klao@1909
  1440
  template<typename UGraph, typename NodeMap>
klao@1909
  1441
  inline bool bipartitePartitions(const UGraph &graph, NodeMap &partMap){
alpar@2260
  1442
    checkConcept<concepts::UGraph, UGraph>();
deba@1800
  1443
    
klao@1909
  1444
    typedef typename UGraph::Node Node;
klao@1909
  1445
    typedef typename UGraph::NodeIt NodeIt;
klao@1909
  1446
    typedef typename UGraph::EdgeIt EdgeIt;
deba@1800
  1447
  
klao@1909
  1448
    Bfs<UGraph> bfs(graph);
deba@1800
  1449
    bfs.init();
deba@1800
  1450
    for(NodeIt i(graph);i!=INVALID;++i){
deba@1800
  1451
      if(!bfs.reached(i)){
deba@1800
  1452
	bfs.addSource(i);
deba@1800
  1453
	for(Node j=bfs.processNextNode();!bfs.emptyQueue();
deba@1800
  1454
	    j=bfs.processNextNode()){
deba@1800
  1455
	  partMap.set(j,bfs.dist(j)%2==0);
deba@1750
  1456
	}
deba@1740
  1457
      }
deba@1740
  1458
    }
deba@1800
  1459
    for(EdgeIt i(graph);i!=INVALID;++i){
deba@1800
  1460
      if(bfs.dist(graph.source(i)) == bfs.dist(graph.target(i)))return false;
deba@1800
  1461
    }
deba@1750
  1462
    return true;
deba@1979
  1463
  }
deba@1750
  1464
   
deba@1698
  1465
} //namespace lemon
deba@1698
  1466
deba@1698
  1467
#endif //LEMON_TOPOLOGY_H