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