lemon/topology.h
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1956 a055123339d5
child 2038 33db14058543
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

The ResGraphAdaptor is based on this composition.
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