lemon/topology.h
author klao
Fri, 10 Mar 2006 18:06:26 +0000
changeset 2003 cf012a7c7f69
parent 1956 a055123339d5
child 2038 33db14058543
permissions -rw-r--r--
UnionFindEnum revision:

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