lemon/topology.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2082 626939628b4a
child 2260 4274224f8a7d
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

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