lemon/connectivity.h
author Akos Ladanyi <ladanyi@tmit.bme.hu>
Wed, 01 Apr 2009 14:18:35 +0100
changeset 611 eda12d8ac953
parent 463 88ed40ad0d4f
child 633 7c12061bd271
permissions -rw-r--r--
Add 'demo' make target for building the demo programs
deba@433
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@433
     2
 *
deba@433
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@433
     4
 *
alpar@463
     5
 * Copyright (C) 2003-2009
deba@433
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@433
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@433
     8
 *
deba@433
     9
 * Permission to use, modify and distribute this software is granted
deba@433
    10
 * provided that this copyright notice appears in all copies. For
deba@433
    11
 * precise terms see the accompanying LICENSE file.
deba@433
    12
 *
deba@433
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@433
    14
 * express or implied, and with no claim as to its suitability for any
deba@433
    15
 * purpose.
deba@433
    16
 *
deba@433
    17
 */
deba@433
    18
deba@435
    19
#ifndef LEMON_CONNECTIVITY_H
deba@435
    20
#define LEMON_CONNECTIVITY_H
deba@433
    21
deba@433
    22
#include <lemon/dfs.h>
deba@433
    23
#include <lemon/bfs.h>
deba@433
    24
#include <lemon/core.h>
deba@433
    25
#include <lemon/maps.h>
deba@433
    26
#include <lemon/adaptors.h>
deba@433
    27
deba@433
    28
#include <lemon/concepts/digraph.h>
deba@433
    29
#include <lemon/concepts/graph.h>
deba@433
    30
#include <lemon/concept_check.h>
deba@433
    31
deba@433
    32
#include <stack>
deba@433
    33
#include <functional>
deba@433
    34
deba@433
    35
/// \ingroup connectivity
deba@433
    36
/// \file
deba@433
    37
/// \brief Connectivity algorithms
deba@433
    38
///
deba@433
    39
/// Connectivity algorithms
deba@433
    40
deba@433
    41
namespace lemon {
deba@433
    42
deba@433
    43
  /// \ingroup connectivity
deba@433
    44
  ///
deba@433
    45
  /// \brief Check whether the given undirected graph is connected.
deba@433
    46
  ///
deba@433
    47
  /// Check whether the given undirected graph is connected.
deba@433
    48
  /// \param graph The undirected graph.
kpeter@606
    49
  /// \return \c true when there is path between any two nodes in the graph.
deba@433
    50
  /// \note By definition, the empty graph is connected.
deba@433
    51
  template <typename Graph>
deba@433
    52
  bool connected(const Graph& graph) {
deba@433
    53
    checkConcept<concepts::Graph, Graph>();
deba@433
    54
    typedef typename Graph::NodeIt NodeIt;
deba@433
    55
    if (NodeIt(graph) == INVALID) return true;
deba@433
    56
    Dfs<Graph> dfs(graph);
deba@433
    57
    dfs.run(NodeIt(graph));
deba@433
    58
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
    59
      if (!dfs.reached(it)) {
deba@433
    60
        return false;
deba@433
    61
      }
deba@433
    62
    }
deba@433
    63
    return true;
deba@433
    64
  }
deba@433
    65
deba@433
    66
  /// \ingroup connectivity
deba@433
    67
  ///
deba@433
    68
  /// \brief Count the number of connected components of an undirected graph
deba@433
    69
  ///
deba@433
    70
  /// Count the number of connected components of an undirected graph
deba@433
    71
  ///
deba@433
    72
  /// \param graph The graph. It must be undirected.
deba@433
    73
  /// \return The number of components
deba@433
    74
  /// \note By definition, the empty graph consists
deba@433
    75
  /// of zero connected components.
deba@433
    76
  template <typename Graph>
deba@433
    77
  int countConnectedComponents(const Graph &graph) {
deba@433
    78
    checkConcept<concepts::Graph, Graph>();
deba@433
    79
    typedef typename Graph::Node Node;
deba@433
    80
    typedef typename Graph::Arc Arc;
deba@433
    81
deba@433
    82
    typedef NullMap<Node, Arc> PredMap;
deba@433
    83
    typedef NullMap<Node, int> DistMap;
deba@433
    84
deba@433
    85
    int compNum = 0;
deba@433
    86
    typename Bfs<Graph>::
deba@433
    87
      template SetPredMap<PredMap>::
deba@433
    88
      template SetDistMap<DistMap>::
deba@433
    89
      Create bfs(graph);
deba@433
    90
deba@433
    91
    PredMap predMap;
deba@433
    92
    bfs.predMap(predMap);
deba@433
    93
deba@433
    94
    DistMap distMap;
deba@433
    95
    bfs.distMap(distMap);
deba@433
    96
deba@433
    97
    bfs.init();
deba@433
    98
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
deba@433
    99
      if (!bfs.reached(n)) {
deba@433
   100
        bfs.addSource(n);
deba@433
   101
        bfs.start();
deba@433
   102
        ++compNum;
deba@433
   103
      }
deba@433
   104
    }
deba@433
   105
    return compNum;
deba@433
   106
  }
deba@433
   107
deba@433
   108
  /// \ingroup connectivity
deba@433
   109
  ///
deba@433
   110
  /// \brief Find the connected components of an undirected graph
deba@433
   111
  ///
deba@433
   112
  /// Find the connected components of an undirected graph.
deba@433
   113
  ///
deba@433
   114
  /// \param graph The graph. It must be undirected.
deba@433
   115
  /// \retval compMap A writable node map. The values will be set from 0 to
deba@433
   116
  /// the number of the connected components minus one. Each values of the map
deba@433
   117
  /// will be set exactly once, the values of a certain component will be
deba@433
   118
  /// set continuously.
deba@433
   119
  /// \return The number of components
deba@433
   120
  ///
deba@433
   121
  template <class Graph, class NodeMap>
deba@433
   122
  int connectedComponents(const Graph &graph, NodeMap &compMap) {
deba@433
   123
    checkConcept<concepts::Graph, Graph>();
deba@433
   124
    typedef typename Graph::Node Node;
deba@433
   125
    typedef typename Graph::Arc Arc;
deba@433
   126
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
deba@433
   127
deba@433
   128
    typedef NullMap<Node, Arc> PredMap;
deba@433
   129
    typedef NullMap<Node, int> DistMap;
deba@433
   130
deba@433
   131
    int compNum = 0;
deba@433
   132
    typename Bfs<Graph>::
deba@433
   133
      template SetPredMap<PredMap>::
deba@433
   134
      template SetDistMap<DistMap>::
deba@433
   135
      Create bfs(graph);
deba@433
   136
deba@433
   137
    PredMap predMap;
deba@433
   138
    bfs.predMap(predMap);
deba@433
   139
deba@433
   140
    DistMap distMap;
deba@433
   141
    bfs.distMap(distMap);
deba@433
   142
deba@433
   143
    bfs.init();
deba@433
   144
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
deba@433
   145
      if(!bfs.reached(n)) {
deba@433
   146
        bfs.addSource(n);
deba@433
   147
        while (!bfs.emptyQueue()) {
deba@433
   148
          compMap.set(bfs.nextNode(), compNum);
deba@433
   149
          bfs.processNextNode();
deba@433
   150
        }
deba@433
   151
        ++compNum;
deba@433
   152
      }
deba@433
   153
    }
deba@433
   154
    return compNum;
deba@433
   155
  }
deba@433
   156
deba@435
   157
  namespace _connectivity_bits {
deba@433
   158
deba@433
   159
    template <typename Digraph, typename Iterator >
deba@433
   160
    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
deba@433
   161
    public:
deba@433
   162
      typedef typename Digraph::Node Node;
deba@433
   163
      LeaveOrderVisitor(Iterator it) : _it(it) {}
deba@433
   164
deba@433
   165
      void leave(const Node& node) {
deba@433
   166
        *(_it++) = node;
deba@433
   167
      }
deba@433
   168
deba@433
   169
    private:
deba@433
   170
      Iterator _it;
deba@433
   171
    };
deba@433
   172
deba@433
   173
    template <typename Digraph, typename Map>
deba@433
   174
    struct FillMapVisitor : public DfsVisitor<Digraph> {
deba@433
   175
    public:
deba@433
   176
      typedef typename Digraph::Node Node;
deba@433
   177
      typedef typename Map::Value Value;
deba@433
   178
deba@433
   179
      FillMapVisitor(Map& map, Value& value)
deba@433
   180
        : _map(map), _value(value) {}
deba@433
   181
deba@433
   182
      void reach(const Node& node) {
deba@433
   183
        _map.set(node, _value);
deba@433
   184
      }
deba@433
   185
    private:
deba@433
   186
      Map& _map;
deba@433
   187
      Value& _value;
deba@433
   188
    };
deba@433
   189
deba@433
   190
    template <typename Digraph, typename ArcMap>
deba@435
   191
    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
deba@433
   192
    public:
deba@433
   193
      typedef typename Digraph::Node Node;
deba@433
   194
      typedef typename Digraph::Arc Arc;
deba@433
   195
deba@435
   196
      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
deba@435
   197
                                      ArcMap& cutMap,
deba@435
   198
                                      int& cutNum)
deba@433
   199
        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
deba@435
   200
          _compMap(digraph, -1), _num(-1) {
deba@433
   201
      }
deba@433
   202
deba@435
   203
      void start(const Node&) {
deba@433
   204
        ++_num;
deba@433
   205
      }
deba@433
   206
deba@433
   207
      void reach(const Node& node) {
deba@433
   208
        _compMap.set(node, _num);
deba@433
   209
      }
deba@433
   210
deba@433
   211
      void examine(const Arc& arc) {
deba@433
   212
         if (_compMap[_digraph.source(arc)] !=
deba@433
   213
             _compMap[_digraph.target(arc)]) {
deba@433
   214
           _cutMap.set(arc, true);
deba@433
   215
           ++_cutNum;
deba@433
   216
         }
deba@433
   217
      }
deba@433
   218
    private:
deba@433
   219
      const Digraph& _digraph;
deba@433
   220
      ArcMap& _cutMap;
deba@433
   221
      int& _cutNum;
deba@433
   222
deba@433
   223
      typename Digraph::template NodeMap<int> _compMap;
deba@433
   224
      int _num;
deba@433
   225
    };
deba@433
   226
deba@433
   227
  }
deba@433
   228
deba@433
   229
deba@433
   230
  /// \ingroup connectivity
deba@433
   231
  ///
deba@433
   232
  /// \brief Check whether the given directed graph is strongly connected.
deba@433
   233
  ///
deba@433
   234
  /// Check whether the given directed graph is strongly connected. The
deba@433
   235
  /// graph is strongly connected when any two nodes of the graph are
deba@433
   236
  /// connected with directed paths in both direction.
kpeter@606
   237
  /// \return \c false when the graph is not strongly connected.
deba@433
   238
  /// \see connected
deba@433
   239
  ///
deba@433
   240
  /// \note By definition, the empty graph is strongly connected.
deba@433
   241
  template <typename Digraph>
deba@433
   242
  bool stronglyConnected(const Digraph& digraph) {
deba@433
   243
    checkConcept<concepts::Digraph, Digraph>();
deba@433
   244
deba@433
   245
    typedef typename Digraph::Node Node;
deba@433
   246
    typedef typename Digraph::NodeIt NodeIt;
deba@433
   247
deba@433
   248
    typename Digraph::Node source = NodeIt(digraph);
deba@433
   249
    if (source == INVALID) return true;
deba@433
   250
deba@435
   251
    using namespace _connectivity_bits;
deba@433
   252
deba@433
   253
    typedef DfsVisitor<Digraph> Visitor;
deba@433
   254
    Visitor visitor;
deba@433
   255
deba@433
   256
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
deba@433
   257
    dfs.init();
deba@433
   258
    dfs.addSource(source);
deba@433
   259
    dfs.start();
deba@433
   260
deba@433
   261
    for (NodeIt it(digraph); it != INVALID; ++it) {
deba@433
   262
      if (!dfs.reached(it)) {
deba@433
   263
        return false;
deba@433
   264
      }
deba@433
   265
    }
deba@433
   266
deba@433
   267
    typedef ReverseDigraph<const Digraph> RDigraph;
deba@435
   268
    typedef typename RDigraph::NodeIt RNodeIt;
deba@433
   269
    RDigraph rdigraph(digraph);
deba@433
   270
deba@433
   271
    typedef DfsVisitor<Digraph> RVisitor;
deba@433
   272
    RVisitor rvisitor;
deba@433
   273
deba@433
   274
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
deba@433
   275
    rdfs.init();
deba@433
   276
    rdfs.addSource(source);
deba@433
   277
    rdfs.start();
deba@433
   278
deba@435
   279
    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
deba@433
   280
      if (!rdfs.reached(it)) {
deba@433
   281
        return false;
deba@433
   282
      }
deba@433
   283
    }
deba@433
   284
deba@433
   285
    return true;
deba@433
   286
  }
deba@433
   287
deba@433
   288
  /// \ingroup connectivity
deba@433
   289
  ///
deba@433
   290
  /// \brief Count the strongly connected components of a directed graph
deba@433
   291
  ///
deba@433
   292
  /// Count the strongly connected components of a directed graph.
deba@433
   293
  /// The strongly connected components are the classes of an
deba@433
   294
  /// equivalence relation on the nodes of the graph. Two nodes are in
deba@433
   295
  /// the same class if they are connected with directed paths in both
deba@433
   296
  /// direction.
deba@433
   297
  ///
deba@444
   298
  /// \param digraph The graph.
deba@433
   299
  /// \return The number of components
deba@433
   300
  /// \note By definition, the empty graph has zero
deba@433
   301
  /// strongly connected components.
deba@433
   302
  template <typename Digraph>
deba@433
   303
  int countStronglyConnectedComponents(const Digraph& digraph) {
deba@433
   304
    checkConcept<concepts::Digraph, Digraph>();
deba@433
   305
deba@435
   306
    using namespace _connectivity_bits;
deba@433
   307
deba@433
   308
    typedef typename Digraph::Node Node;
deba@433
   309
    typedef typename Digraph::Arc Arc;
deba@433
   310
    typedef typename Digraph::NodeIt NodeIt;
deba@433
   311
    typedef typename Digraph::ArcIt ArcIt;
deba@433
   312
deba@433
   313
    typedef std::vector<Node> Container;
deba@433
   314
    typedef typename Container::iterator Iterator;
deba@433
   315
deba@433
   316
    Container nodes(countNodes(digraph));
deba@433
   317
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
deba@433
   318
    Visitor visitor(nodes.begin());
deba@433
   319
deba@433
   320
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
deba@433
   321
    dfs.init();
deba@433
   322
    for (NodeIt it(digraph); it != INVALID; ++it) {
deba@433
   323
      if (!dfs.reached(it)) {
deba@433
   324
        dfs.addSource(it);
deba@433
   325
        dfs.start();
deba@433
   326
      }
deba@433
   327
    }
deba@433
   328
deba@433
   329
    typedef typename Container::reverse_iterator RIterator;
deba@433
   330
    typedef ReverseDigraph<const Digraph> RDigraph;
deba@433
   331
deba@433
   332
    RDigraph rdigraph(digraph);
deba@433
   333
deba@433
   334
    typedef DfsVisitor<Digraph> RVisitor;
deba@433
   335
    RVisitor rvisitor;
deba@433
   336
deba@433
   337
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
deba@433
   338
deba@433
   339
    int compNum = 0;
deba@433
   340
deba@433
   341
    rdfs.init();
deba@433
   342
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@433
   343
      if (!rdfs.reached(*it)) {
deba@433
   344
        rdfs.addSource(*it);
deba@433
   345
        rdfs.start();
deba@433
   346
        ++compNum;
deba@433
   347
      }
deba@433
   348
    }
deba@433
   349
    return compNum;
deba@433
   350
  }
deba@433
   351
deba@433
   352
  /// \ingroup connectivity
deba@433
   353
  ///
deba@433
   354
  /// \brief Find the strongly connected components of a directed graph
deba@433
   355
  ///
deba@433
   356
  /// Find the strongly connected components of a directed graph.  The
deba@433
   357
  /// strongly connected components are the classes of an equivalence
deba@433
   358
  /// relation on the nodes of the graph. Two nodes are in
deba@433
   359
  /// relationship when there are directed paths between them in both
deba@433
   360
  /// direction. In addition, the numbering of components will satisfy
deba@433
   361
  /// that there is no arc going from a higher numbered component to
deba@433
   362
  /// a lower.
deba@433
   363
  ///
deba@433
   364
  /// \param digraph The digraph.
deba@433
   365
  /// \retval compMap A writable node map. The values will be set from 0 to
deba@433
   366
  /// the number of the strongly connected components minus one. Each value
deba@433
   367
  /// of the map will be set exactly once, the values of a certain component
deba@433
   368
  /// will be set continuously.
deba@433
   369
  /// \return The number of components
deba@433
   370
  ///
deba@433
   371
  template <typename Digraph, typename NodeMap>
deba@433
   372
  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
deba@433
   373
    checkConcept<concepts::Digraph, Digraph>();
deba@433
   374
    typedef typename Digraph::Node Node;
deba@433
   375
    typedef typename Digraph::NodeIt NodeIt;
deba@433
   376
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
deba@433
   377
deba@435
   378
    using namespace _connectivity_bits;
deba@433
   379
deba@433
   380
    typedef std::vector<Node> Container;
deba@433
   381
    typedef typename Container::iterator Iterator;
deba@433
   382
deba@433
   383
    Container nodes(countNodes(digraph));
deba@433
   384
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
deba@433
   385
    Visitor visitor(nodes.begin());
deba@433
   386
deba@433
   387
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
deba@433
   388
    dfs.init();
deba@433
   389
    for (NodeIt it(digraph); it != INVALID; ++it) {
deba@433
   390
      if (!dfs.reached(it)) {
deba@433
   391
        dfs.addSource(it);
deba@433
   392
        dfs.start();
deba@433
   393
      }
deba@433
   394
    }
deba@433
   395
deba@433
   396
    typedef typename Container::reverse_iterator RIterator;
deba@433
   397
    typedef ReverseDigraph<const Digraph> RDigraph;
deba@433
   398
deba@433
   399
    RDigraph rdigraph(digraph);
deba@433
   400
deba@433
   401
    int compNum = 0;
deba@433
   402
deba@433
   403
    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
deba@433
   404
    RVisitor rvisitor(compMap, compNum);
deba@433
   405
deba@433
   406
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
deba@433
   407
deba@433
   408
    rdfs.init();
deba@433
   409
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@433
   410
      if (!rdfs.reached(*it)) {
deba@433
   411
        rdfs.addSource(*it);
deba@433
   412
        rdfs.start();
deba@433
   413
        ++compNum;
deba@433
   414
      }
deba@433
   415
    }
deba@433
   416
    return compNum;
deba@433
   417
  }
deba@433
   418
deba@433
   419
  /// \ingroup connectivity
deba@433
   420
  ///
deba@433
   421
  /// \brief Find the cut arcs of the strongly connected components.
deba@433
   422
  ///
deba@433
   423
  /// Find the cut arcs of the strongly connected components.
deba@433
   424
  /// The strongly connected components are the classes of an equivalence
deba@433
   425
  /// relation on the nodes of the graph. Two nodes are in relationship
deba@433
   426
  /// when there are directed paths between them in both direction.
deba@433
   427
  /// The strongly connected components are separated by the cut arcs.
deba@433
   428
  ///
deba@433
   429
  /// \param graph The graph.
deba@433
   430
  /// \retval cutMap A writable node map. The values will be set true when the
deba@433
   431
  /// arc is a cut arc.
deba@433
   432
  ///
deba@433
   433
  /// \return The number of cut arcs
deba@433
   434
  template <typename Digraph, typename ArcMap>
deba@433
   435
  int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
deba@433
   436
    checkConcept<concepts::Digraph, Digraph>();
deba@433
   437
    typedef typename Digraph::Node Node;
deba@433
   438
    typedef typename Digraph::Arc Arc;
deba@433
   439
    typedef typename Digraph::NodeIt NodeIt;
deba@433
   440
    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
deba@433
   441
deba@435
   442
    using namespace _connectivity_bits;
deba@433
   443
deba@433
   444
    typedef std::vector<Node> Container;
deba@433
   445
    typedef typename Container::iterator Iterator;
deba@433
   446
deba@433
   447
    Container nodes(countNodes(graph));
deba@433
   448
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
deba@433
   449
    Visitor visitor(nodes.begin());
deba@433
   450
deba@433
   451
    DfsVisit<Digraph, Visitor> dfs(graph, visitor);
deba@433
   452
    dfs.init();
deba@433
   453
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
   454
      if (!dfs.reached(it)) {
deba@433
   455
        dfs.addSource(it);
deba@433
   456
        dfs.start();
deba@433
   457
      }
deba@433
   458
    }
deba@433
   459
deba@433
   460
    typedef typename Container::reverse_iterator RIterator;
deba@433
   461
    typedef ReverseDigraph<const Digraph> RDigraph;
deba@433
   462
deba@433
   463
    RDigraph rgraph(graph);
deba@433
   464
deba@433
   465
    int cutNum = 0;
deba@433
   466
deba@435
   467
    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
deba@433
   468
    RVisitor rvisitor(rgraph, cutMap, cutNum);
deba@433
   469
deba@433
   470
    DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
deba@433
   471
deba@433
   472
    rdfs.init();
deba@433
   473
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
deba@433
   474
      if (!rdfs.reached(*it)) {
deba@433
   475
        rdfs.addSource(*it);
deba@433
   476
        rdfs.start();
deba@433
   477
      }
deba@433
   478
    }
deba@433
   479
    return cutNum;
deba@433
   480
  }
deba@433
   481
deba@435
   482
  namespace _connectivity_bits {
deba@433
   483
deba@433
   484
    template <typename Digraph>
deba@433
   485
    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
deba@433
   486
    public:
deba@433
   487
      typedef typename Digraph::Node Node;
deba@433
   488
      typedef typename Digraph::Arc Arc;
deba@433
   489
      typedef typename Digraph::Edge Edge;
deba@433
   490
deba@433
   491
      CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
deba@433
   492
        : _graph(graph), _compNum(compNum),
deba@433
   493
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@433
   494
deba@433
   495
      void start(const Node& node) {
deba@433
   496
        _predMap.set(node, INVALID);
deba@433
   497
      }
deba@433
   498
deba@433
   499
      void reach(const Node& node) {
deba@433
   500
        _numMap.set(node, _num);
deba@433
   501
        _retMap.set(node, _num);
deba@433
   502
        ++_num;
deba@433
   503
      }
deba@433
   504
deba@433
   505
      void discover(const Arc& edge) {
deba@433
   506
        _predMap.set(_graph.target(edge), _graph.source(edge));
deba@433
   507
      }
deba@433
   508
deba@433
   509
      void examine(const Arc& edge) {
deba@433
   510
        if (_graph.source(edge) == _graph.target(edge) &&
deba@433
   511
            _graph.direction(edge)) {
deba@433
   512
          ++_compNum;
deba@433
   513
          return;
deba@433
   514
        }
deba@433
   515
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
deba@433
   516
          return;
deba@433
   517
        }
deba@433
   518
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
deba@433
   519
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
deba@433
   520
        }
deba@433
   521
      }
deba@433
   522
deba@433
   523
      void backtrack(const Arc& edge) {
deba@433
   524
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@433
   525
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@433
   526
        }
deba@433
   527
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
deba@433
   528
          ++_compNum;
deba@433
   529
        }
deba@433
   530
      }
deba@433
   531
deba@433
   532
    private:
deba@433
   533
      const Digraph& _graph;
deba@433
   534
      int& _compNum;
deba@433
   535
deba@433
   536
      typename Digraph::template NodeMap<int> _numMap;
deba@433
   537
      typename Digraph::template NodeMap<int> _retMap;
deba@433
   538
      typename Digraph::template NodeMap<Node> _predMap;
deba@433
   539
      int _num;
deba@433
   540
    };
deba@433
   541
deba@433
   542
    template <typename Digraph, typename ArcMap>
deba@433
   543
    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
deba@433
   544
    public:
deba@433
   545
      typedef typename Digraph::Node Node;
deba@433
   546
      typedef typename Digraph::Arc Arc;
deba@433
   547
      typedef typename Digraph::Edge Edge;
deba@433
   548
deba@433
   549
      BiNodeConnectedComponentsVisitor(const Digraph& graph,
deba@433
   550
                                       ArcMap& compMap, int &compNum)
deba@433
   551
        : _graph(graph), _compMap(compMap), _compNum(compNum),
deba@433
   552
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@433
   553
deba@433
   554
      void start(const Node& node) {
deba@433
   555
        _predMap.set(node, INVALID);
deba@433
   556
      }
deba@433
   557
deba@433
   558
      void reach(const Node& node) {
deba@433
   559
        _numMap.set(node, _num);
deba@433
   560
        _retMap.set(node, _num);
deba@433
   561
        ++_num;
deba@433
   562
      }
deba@433
   563
deba@433
   564
      void discover(const Arc& edge) {
deba@433
   565
        Node target = _graph.target(edge);
deba@433
   566
        _predMap.set(target, edge);
deba@433
   567
        _edgeStack.push(edge);
deba@433
   568
      }
deba@433
   569
deba@433
   570
      void examine(const Arc& edge) {
deba@433
   571
        Node source = _graph.source(edge);
deba@433
   572
        Node target = _graph.target(edge);
deba@433
   573
        if (source == target && _graph.direction(edge)) {
deba@433
   574
          _compMap.set(edge, _compNum);
deba@433
   575
          ++_compNum;
deba@433
   576
          return;
deba@433
   577
        }
deba@433
   578
        if (_numMap[target] < _numMap[source]) {
deba@433
   579
          if (_predMap[source] != _graph.oppositeArc(edge)) {
deba@433
   580
            _edgeStack.push(edge);
deba@433
   581
          }
deba@433
   582
        }
deba@433
   583
        if (_predMap[source] != INVALID &&
deba@433
   584
            target == _graph.source(_predMap[source])) {
deba@433
   585
          return;
deba@433
   586
        }
deba@433
   587
        if (_retMap[source] > _numMap[target]) {
deba@433
   588
          _retMap.set(source, _numMap[target]);
deba@433
   589
        }
deba@433
   590
      }
deba@433
   591
deba@433
   592
      void backtrack(const Arc& edge) {
deba@433
   593
        Node source = _graph.source(edge);
deba@433
   594
        Node target = _graph.target(edge);
deba@433
   595
        if (_retMap[source] > _retMap[target]) {
deba@433
   596
          _retMap.set(source, _retMap[target]);
deba@433
   597
        }
deba@433
   598
        if (_numMap[source] <= _retMap[target]) {
deba@433
   599
          while (_edgeStack.top() != edge) {
deba@433
   600
            _compMap.set(_edgeStack.top(), _compNum);
deba@433
   601
            _edgeStack.pop();
deba@433
   602
          }
deba@433
   603
          _compMap.set(edge, _compNum);
deba@433
   604
          _edgeStack.pop();
deba@433
   605
          ++_compNum;
deba@433
   606
        }
deba@433
   607
      }
deba@433
   608
deba@433
   609
    private:
deba@433
   610
      const Digraph& _graph;
deba@433
   611
      ArcMap& _compMap;
deba@433
   612
      int& _compNum;
deba@433
   613
deba@433
   614
      typename Digraph::template NodeMap<int> _numMap;
deba@433
   615
      typename Digraph::template NodeMap<int> _retMap;
deba@433
   616
      typename Digraph::template NodeMap<Arc> _predMap;
deba@433
   617
      std::stack<Edge> _edgeStack;
deba@433
   618
      int _num;
deba@433
   619
    };
deba@433
   620
deba@433
   621
deba@433
   622
    template <typename Digraph, typename NodeMap>
deba@433
   623
    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
deba@433
   624
    public:
deba@433
   625
      typedef typename Digraph::Node Node;
deba@433
   626
      typedef typename Digraph::Arc Arc;
deba@433
   627
      typedef typename Digraph::Edge Edge;
deba@433
   628
deba@433
   629
      BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
deba@433
   630
                                     int& cutNum)
deba@433
   631
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
deba@433
   632
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@433
   633
deba@433
   634
      void start(const Node& node) {
deba@433
   635
        _predMap.set(node, INVALID);
deba@433
   636
        rootCut = false;
deba@433
   637
      }
deba@433
   638
deba@433
   639
      void reach(const Node& node) {
deba@433
   640
        _numMap.set(node, _num);
deba@433
   641
        _retMap.set(node, _num);
deba@433
   642
        ++_num;
deba@433
   643
      }
deba@433
   644
deba@433
   645
      void discover(const Arc& edge) {
deba@433
   646
        _predMap.set(_graph.target(edge), _graph.source(edge));
deba@433
   647
      }
deba@433
   648
deba@433
   649
      void examine(const Arc& edge) {
deba@433
   650
        if (_graph.source(edge) == _graph.target(edge) &&
deba@433
   651
            _graph.direction(edge)) {
deba@433
   652
          if (!_cutMap[_graph.source(edge)]) {
deba@433
   653
            _cutMap.set(_graph.source(edge), true);
deba@433
   654
            ++_cutNum;
deba@433
   655
          }
deba@433
   656
          return;
deba@433
   657
        }
deba@433
   658
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
deba@433
   659
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
deba@433
   660
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
deba@433
   661
        }
deba@433
   662
      }
deba@433
   663
deba@433
   664
      void backtrack(const Arc& edge) {
deba@433
   665
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@433
   666
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@433
   667
        }
deba@433
   668
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
deba@433
   669
          if (_predMap[_graph.source(edge)] != INVALID) {
deba@433
   670
            if (!_cutMap[_graph.source(edge)]) {
deba@433
   671
              _cutMap.set(_graph.source(edge), true);
deba@433
   672
              ++_cutNum;
deba@433
   673
            }
deba@433
   674
          } else if (rootCut) {
deba@433
   675
            if (!_cutMap[_graph.source(edge)]) {
deba@433
   676
              _cutMap.set(_graph.source(edge), true);
deba@433
   677
              ++_cutNum;
deba@433
   678
            }
deba@433
   679
          } else {
deba@433
   680
            rootCut = true;
deba@433
   681
          }
deba@433
   682
        }
deba@433
   683
      }
deba@433
   684
deba@433
   685
    private:
deba@433
   686
      const Digraph& _graph;
deba@433
   687
      NodeMap& _cutMap;
deba@433
   688
      int& _cutNum;
deba@433
   689
deba@433
   690
      typename Digraph::template NodeMap<int> _numMap;
deba@433
   691
      typename Digraph::template NodeMap<int> _retMap;
deba@433
   692
      typename Digraph::template NodeMap<Node> _predMap;
deba@433
   693
      std::stack<Edge> _edgeStack;
deba@433
   694
      int _num;
deba@433
   695
      bool rootCut;
deba@433
   696
    };
deba@433
   697
deba@433
   698
  }
deba@433
   699
deba@433
   700
  template <typename Graph>
deba@433
   701
  int countBiNodeConnectedComponents(const Graph& graph);
deba@433
   702
deba@433
   703
  /// \ingroup connectivity
deba@433
   704
  ///
deba@433
   705
  /// \brief Checks the graph is bi-node-connected.
deba@433
   706
  ///
deba@433
   707
  /// This function checks that the undirected graph is bi-node-connected
deba@433
   708
  /// graph. The graph is bi-node-connected if any two undirected edge is
deba@433
   709
  /// on same circle.
deba@433
   710
  ///
deba@433
   711
  /// \param graph The graph.
kpeter@606
   712
  /// \return \c true when the graph bi-node-connected.
deba@433
   713
  template <typename Graph>
deba@433
   714
  bool biNodeConnected(const Graph& graph) {
deba@433
   715
    return countBiNodeConnectedComponents(graph) <= 1;
deba@433
   716
  }
deba@433
   717
deba@433
   718
  /// \ingroup connectivity
deba@433
   719
  ///
deba@433
   720
  /// \brief Count the biconnected components.
deba@433
   721
  ///
deba@433
   722
  /// This function finds the bi-node-connected components in an undirected
deba@433
   723
  /// graph. The biconnected components are the classes of an equivalence
deba@433
   724
  /// relation on the undirected edges. Two undirected edge is in relationship
deba@433
   725
  /// when they are on same circle.
deba@433
   726
  ///
deba@433
   727
  /// \param graph The graph.
deba@433
   728
  /// \return The number of components.
deba@433
   729
  template <typename Graph>
deba@433
   730
  int countBiNodeConnectedComponents(const Graph& graph) {
deba@433
   731
    checkConcept<concepts::Graph, Graph>();
deba@433
   732
    typedef typename Graph::NodeIt NodeIt;
deba@433
   733
deba@435
   734
    using namespace _connectivity_bits;
deba@433
   735
deba@433
   736
    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
deba@433
   737
deba@433
   738
    int compNum = 0;
deba@433
   739
    Visitor visitor(graph, compNum);
deba@433
   740
deba@433
   741
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@433
   742
    dfs.init();
deba@433
   743
deba@433
   744
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
   745
      if (!dfs.reached(it)) {
deba@433
   746
        dfs.addSource(it);
deba@433
   747
        dfs.start();
deba@433
   748
      }
deba@433
   749
    }
deba@433
   750
    return compNum;
deba@433
   751
  }
deba@433
   752
deba@433
   753
  /// \ingroup connectivity
deba@433
   754
  ///
deba@433
   755
  /// \brief Find the bi-node-connected components.
deba@433
   756
  ///
deba@433
   757
  /// This function finds the bi-node-connected components in an undirected
deba@433
   758
  /// graph. The bi-node-connected components are the classes of an equivalence
deba@433
   759
  /// relation on the undirected edges. Two undirected edge are in relationship
deba@433
   760
  /// when they are on same circle.
deba@433
   761
  ///
deba@433
   762
  /// \param graph The graph.
deba@433
   763
  /// \retval compMap A writable uedge map. The values will be set from 0
deba@433
   764
  /// to the number of the biconnected components minus one. Each values
deba@433
   765
  /// of the map will be set exactly once, the values of a certain component
deba@433
   766
  /// will be set continuously.
deba@433
   767
  /// \return The number of components.
deba@433
   768
  ///
deba@433
   769
  template <typename Graph, typename EdgeMap>
deba@433
   770
  int biNodeConnectedComponents(const Graph& graph,
deba@433
   771
                                EdgeMap& compMap) {
deba@433
   772
    checkConcept<concepts::Graph, Graph>();
deba@433
   773
    typedef typename Graph::NodeIt NodeIt;
deba@433
   774
    typedef typename Graph::Edge Edge;
deba@433
   775
    checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
deba@433
   776
deba@435
   777
    using namespace _connectivity_bits;
deba@433
   778
deba@433
   779
    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
deba@433
   780
deba@433
   781
    int compNum = 0;
deba@433
   782
    Visitor visitor(graph, compMap, compNum);
deba@433
   783
deba@433
   784
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@433
   785
    dfs.init();
deba@433
   786
deba@433
   787
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
   788
      if (!dfs.reached(it)) {
deba@433
   789
        dfs.addSource(it);
deba@433
   790
        dfs.start();
deba@433
   791
      }
deba@433
   792
    }
deba@433
   793
    return compNum;
deba@433
   794
  }
deba@433
   795
deba@433
   796
  /// \ingroup connectivity
deba@433
   797
  ///
deba@433
   798
  /// \brief Find the bi-node-connected cut nodes.
deba@433
   799
  ///
deba@433
   800
  /// This function finds the bi-node-connected cut nodes in an undirected
deba@433
   801
  /// graph. The bi-node-connected components are the classes of an equivalence
deba@433
   802
  /// relation on the undirected edges. Two undirected edges are in
deba@433
   803
  /// relationship when they are on same circle. The biconnected components
deba@433
   804
  /// are separted by nodes which are the cut nodes of the components.
deba@433
   805
  ///
deba@433
   806
  /// \param graph The graph.
deba@433
   807
  /// \retval cutMap A writable edge map. The values will be set true when
deba@433
   808
  /// the node separate two or more components.
deba@433
   809
  /// \return The number of the cut nodes.
deba@433
   810
  template <typename Graph, typename NodeMap>
deba@433
   811
  int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
deba@433
   812
    checkConcept<concepts::Graph, Graph>();
deba@433
   813
    typedef typename Graph::Node Node;
deba@433
   814
    typedef typename Graph::NodeIt NodeIt;
deba@433
   815
    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
deba@433
   816
deba@435
   817
    using namespace _connectivity_bits;
deba@433
   818
deba@433
   819
    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
deba@433
   820
deba@433
   821
    int cutNum = 0;
deba@433
   822
    Visitor visitor(graph, cutMap, cutNum);
deba@433
   823
deba@433
   824
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@433
   825
    dfs.init();
deba@433
   826
deba@433
   827
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
   828
      if (!dfs.reached(it)) {
deba@433
   829
        dfs.addSource(it);
deba@433
   830
        dfs.start();
deba@433
   831
      }
deba@433
   832
    }
deba@433
   833
    return cutNum;
deba@433
   834
  }
deba@433
   835
deba@435
   836
  namespace _connectivity_bits {
deba@433
   837
deba@433
   838
    template <typename Digraph>
deba@433
   839
    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
deba@433
   840
    public:
deba@433
   841
      typedef typename Digraph::Node Node;
deba@433
   842
      typedef typename Digraph::Arc Arc;
deba@433
   843
      typedef typename Digraph::Edge Edge;
deba@433
   844
deba@433
   845
      CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
deba@433
   846
        : _graph(graph), _compNum(compNum),
deba@433
   847
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@433
   848
deba@433
   849
      void start(const Node& node) {
deba@433
   850
        _predMap.set(node, INVALID);
deba@433
   851
      }
deba@433
   852
deba@433
   853
      void reach(const Node& node) {
deba@433
   854
        _numMap.set(node, _num);
deba@433
   855
        _retMap.set(node, _num);
deba@433
   856
        ++_num;
deba@433
   857
      }
deba@433
   858
deba@433
   859
      void leave(const Node& node) {
deba@433
   860
        if (_numMap[node] <= _retMap[node]) {
deba@433
   861
          ++_compNum;
deba@433
   862
        }
deba@433
   863
      }
deba@433
   864
deba@433
   865
      void discover(const Arc& edge) {
deba@433
   866
        _predMap.set(_graph.target(edge), edge);
deba@433
   867
      }
deba@433
   868
deba@433
   869
      void examine(const Arc& edge) {
deba@433
   870
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
deba@433
   871
          return;
deba@433
   872
        }
deba@433
   873
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@433
   874
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@433
   875
        }
deba@433
   876
      }
deba@433
   877
deba@433
   878
      void backtrack(const Arc& edge) {
deba@433
   879
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@433
   880
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@433
   881
        }
deba@433
   882
      }
deba@433
   883
deba@433
   884
    private:
deba@433
   885
      const Digraph& _graph;
deba@433
   886
      int& _compNum;
deba@433
   887
deba@433
   888
      typename Digraph::template NodeMap<int> _numMap;
deba@433
   889
      typename Digraph::template NodeMap<int> _retMap;
deba@433
   890
      typename Digraph::template NodeMap<Arc> _predMap;
deba@433
   891
      int _num;
deba@433
   892
    };
deba@433
   893
deba@433
   894
    template <typename Digraph, typename NodeMap>
deba@433
   895
    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
deba@433
   896
    public:
deba@433
   897
      typedef typename Digraph::Node Node;
deba@433
   898
      typedef typename Digraph::Arc Arc;
deba@433
   899
      typedef typename Digraph::Edge Edge;
deba@433
   900
deba@433
   901
      BiEdgeConnectedComponentsVisitor(const Digraph& graph,
deba@433
   902
                                       NodeMap& compMap, int &compNum)
deba@433
   903
        : _graph(graph), _compMap(compMap), _compNum(compNum),
deba@433
   904
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@433
   905
deba@433
   906
      void start(const Node& node) {
deba@433
   907
        _predMap.set(node, INVALID);
deba@433
   908
      }
deba@433
   909
deba@433
   910
      void reach(const Node& node) {
deba@433
   911
        _numMap.set(node, _num);
deba@433
   912
        _retMap.set(node, _num);
deba@433
   913
        _nodeStack.push(node);
deba@433
   914
        ++_num;
deba@433
   915
      }
deba@433
   916
deba@433
   917
      void leave(const Node& node) {
deba@433
   918
        if (_numMap[node] <= _retMap[node]) {
deba@433
   919
          while (_nodeStack.top() != node) {
deba@433
   920
            _compMap.set(_nodeStack.top(), _compNum);
deba@433
   921
            _nodeStack.pop();
deba@433
   922
          }
deba@433
   923
          _compMap.set(node, _compNum);
deba@433
   924
          _nodeStack.pop();
deba@433
   925
          ++_compNum;
deba@433
   926
        }
deba@433
   927
      }
deba@433
   928
deba@433
   929
      void discover(const Arc& edge) {
deba@433
   930
        _predMap.set(_graph.target(edge), edge);
deba@433
   931
      }
deba@433
   932
deba@433
   933
      void examine(const Arc& edge) {
deba@433
   934
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
deba@433
   935
          return;
deba@433
   936
        }
deba@433
   937
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@433
   938
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@433
   939
        }
deba@433
   940
      }
deba@433
   941
deba@433
   942
      void backtrack(const Arc& edge) {
deba@433
   943
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@433
   944
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@433
   945
        }
deba@433
   946
      }
deba@433
   947
deba@433
   948
    private:
deba@433
   949
      const Digraph& _graph;
deba@433
   950
      NodeMap& _compMap;
deba@433
   951
      int& _compNum;
deba@433
   952
deba@433
   953
      typename Digraph::template NodeMap<int> _numMap;
deba@433
   954
      typename Digraph::template NodeMap<int> _retMap;
deba@433
   955
      typename Digraph::template NodeMap<Arc> _predMap;
deba@433
   956
      std::stack<Node> _nodeStack;
deba@433
   957
      int _num;
deba@433
   958
    };
deba@433
   959
deba@433
   960
deba@433
   961
    template <typename Digraph, typename ArcMap>
deba@433
   962
    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
deba@433
   963
    public:
deba@433
   964
      typedef typename Digraph::Node Node;
deba@433
   965
      typedef typename Digraph::Arc Arc;
deba@433
   966
      typedef typename Digraph::Edge Edge;
deba@433
   967
deba@433
   968
      BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
deba@433
   969
                                     ArcMap& cutMap, int &cutNum)
deba@433
   970
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
deba@433
   971
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
deba@433
   972
deba@433
   973
      void start(const Node& node) {
deba@433
   974
        _predMap[node] = INVALID;
deba@433
   975
      }
deba@433
   976
deba@433
   977
      void reach(const Node& node) {
deba@433
   978
        _numMap.set(node, _num);
deba@433
   979
        _retMap.set(node, _num);
deba@433
   980
        ++_num;
deba@433
   981
      }
deba@433
   982
deba@433
   983
      void leave(const Node& node) {
deba@433
   984
        if (_numMap[node] <= _retMap[node]) {
deba@433
   985
          if (_predMap[node] != INVALID) {
deba@433
   986
            _cutMap.set(_predMap[node], true);
deba@433
   987
            ++_cutNum;
deba@433
   988
          }
deba@433
   989
        }
deba@433
   990
      }
deba@433
   991
deba@433
   992
      void discover(const Arc& edge) {
deba@433
   993
        _predMap.set(_graph.target(edge), edge);
deba@433
   994
      }
deba@433
   995
deba@433
   996
      void examine(const Arc& edge) {
deba@433
   997
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
deba@433
   998
          return;
deba@433
   999
        }
deba@433
  1000
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@433
  1001
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@433
  1002
        }
deba@433
  1003
      }
deba@433
  1004
deba@433
  1005
      void backtrack(const Arc& edge) {
deba@433
  1006
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
deba@433
  1007
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
deba@433
  1008
        }
deba@433
  1009
      }
deba@433
  1010
deba@433
  1011
    private:
deba@433
  1012
      const Digraph& _graph;
deba@433
  1013
      ArcMap& _cutMap;
deba@433
  1014
      int& _cutNum;
deba@433
  1015
deba@433
  1016
      typename Digraph::template NodeMap<int> _numMap;
deba@433
  1017
      typename Digraph::template NodeMap<int> _retMap;
deba@433
  1018
      typename Digraph::template NodeMap<Arc> _predMap;
deba@433
  1019
      int _num;
deba@433
  1020
    };
deba@433
  1021
  }
deba@433
  1022
deba@433
  1023
  template <typename Graph>
deba@433
  1024
  int countBiEdgeConnectedComponents(const Graph& graph);
deba@433
  1025
deba@433
  1026
  /// \ingroup connectivity
deba@433
  1027
  ///
deba@433
  1028
  /// \brief Checks that the graph is bi-edge-connected.
deba@433
  1029
  ///
deba@433
  1030
  /// This function checks that the graph is bi-edge-connected. The undirected
deba@433
  1031
  /// graph is bi-edge-connected when any two nodes are connected with two
deba@433
  1032
  /// edge-disjoint paths.
deba@433
  1033
  ///
deba@433
  1034
  /// \param graph The undirected graph.
deba@433
  1035
  /// \return The number of components.
deba@433
  1036
  template <typename Graph>
deba@433
  1037
  bool biEdgeConnected(const Graph& graph) {
deba@433
  1038
    return countBiEdgeConnectedComponents(graph) <= 1;
deba@433
  1039
  }
deba@433
  1040
deba@433
  1041
  /// \ingroup connectivity
deba@433
  1042
  ///
deba@433
  1043
  /// \brief Count the bi-edge-connected components.
deba@433
  1044
  ///
deba@433
  1045
  /// This function count the bi-edge-connected components in an undirected
deba@433
  1046
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@433
  1047
  /// relation on the nodes. Two nodes are in relationship when they are
deba@433
  1048
  /// connected with at least two edge-disjoint paths.
deba@433
  1049
  ///
deba@433
  1050
  /// \param graph The undirected graph.
deba@433
  1051
  /// \return The number of components.
deba@433
  1052
  template <typename Graph>
deba@433
  1053
  int countBiEdgeConnectedComponents(const Graph& graph) {
deba@433
  1054
    checkConcept<concepts::Graph, Graph>();
deba@433
  1055
    typedef typename Graph::NodeIt NodeIt;
deba@433
  1056
deba@435
  1057
    using namespace _connectivity_bits;
deba@433
  1058
deba@433
  1059
    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
deba@433
  1060
deba@433
  1061
    int compNum = 0;
deba@433
  1062
    Visitor visitor(graph, compNum);
deba@433
  1063
deba@433
  1064
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@433
  1065
    dfs.init();
deba@433
  1066
deba@433
  1067
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
  1068
      if (!dfs.reached(it)) {
deba@433
  1069
        dfs.addSource(it);
deba@433
  1070
        dfs.start();
deba@433
  1071
      }
deba@433
  1072
    }
deba@433
  1073
    return compNum;
deba@433
  1074
  }
deba@433
  1075
deba@433
  1076
  /// \ingroup connectivity
deba@433
  1077
  ///
deba@433
  1078
  /// \brief Find the bi-edge-connected components.
deba@433
  1079
  ///
deba@433
  1080
  /// This function finds the bi-edge-connected components in an undirected
deba@433
  1081
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@433
  1082
  /// relation on the nodes. Two nodes are in relationship when they are
deba@433
  1083
  /// connected at least two edge-disjoint paths.
deba@433
  1084
  ///
deba@433
  1085
  /// \param graph The graph.
deba@433
  1086
  /// \retval compMap A writable node map. The values will be set from 0 to
deba@433
  1087
  /// the number of the biconnected components minus one. Each values
deba@433
  1088
  /// of the map will be set exactly once, the values of a certain component
deba@433
  1089
  /// will be set continuously.
deba@433
  1090
  /// \return The number of components.
deba@433
  1091
  ///
deba@433
  1092
  template <typename Graph, typename NodeMap>
deba@433
  1093
  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
deba@433
  1094
    checkConcept<concepts::Graph, Graph>();
deba@433
  1095
    typedef typename Graph::NodeIt NodeIt;
deba@433
  1096
    typedef typename Graph::Node Node;
deba@433
  1097
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
deba@433
  1098
deba@435
  1099
    using namespace _connectivity_bits;
deba@433
  1100
deba@433
  1101
    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
deba@433
  1102
deba@433
  1103
    int compNum = 0;
deba@433
  1104
    Visitor visitor(graph, compMap, compNum);
deba@433
  1105
deba@433
  1106
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@433
  1107
    dfs.init();
deba@433
  1108
deba@433
  1109
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
  1110
      if (!dfs.reached(it)) {
deba@433
  1111
        dfs.addSource(it);
deba@433
  1112
        dfs.start();
deba@433
  1113
      }
deba@433
  1114
    }
deba@433
  1115
    return compNum;
deba@433
  1116
  }
deba@433
  1117
deba@433
  1118
  /// \ingroup connectivity
deba@433
  1119
  ///
deba@433
  1120
  /// \brief Find the bi-edge-connected cut edges.
deba@433
  1121
  ///
deba@433
  1122
  /// This function finds the bi-edge-connected components in an undirected
deba@433
  1123
  /// graph. The bi-edge-connected components are the classes of an equivalence
deba@433
  1124
  /// relation on the nodes. Two nodes are in relationship when they are
deba@433
  1125
  /// connected with at least two edge-disjoint paths. The bi-edge-connected
deba@433
  1126
  /// components are separted by edges which are the cut edges of the
deba@433
  1127
  /// components.
deba@433
  1128
  ///
deba@433
  1129
  /// \param graph The graph.
deba@433
  1130
  /// \retval cutMap A writable node map. The values will be set true when the
deba@433
  1131
  /// edge is a cut edge.
deba@433
  1132
  /// \return The number of cut edges.
deba@433
  1133
  template <typename Graph, typename EdgeMap>
deba@433
  1134
  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
deba@433
  1135
    checkConcept<concepts::Graph, Graph>();
deba@433
  1136
    typedef typename Graph::NodeIt NodeIt;
deba@433
  1137
    typedef typename Graph::Edge Edge;
deba@433
  1138
    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
deba@433
  1139
deba@435
  1140
    using namespace _connectivity_bits;
deba@433
  1141
deba@433
  1142
    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
deba@433
  1143
deba@433
  1144
    int cutNum = 0;
deba@433
  1145
    Visitor visitor(graph, cutMap, cutNum);
deba@433
  1146
deba@433
  1147
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
deba@433
  1148
    dfs.init();
deba@433
  1149
deba@433
  1150
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
  1151
      if (!dfs.reached(it)) {
deba@433
  1152
        dfs.addSource(it);
deba@433
  1153
        dfs.start();
deba@433
  1154
      }
deba@433
  1155
    }
deba@433
  1156
    return cutNum;
deba@433
  1157
  }
deba@433
  1158
deba@433
  1159
deba@435
  1160
  namespace _connectivity_bits {
deba@433
  1161
deba@433
  1162
    template <typename Digraph, typename IntNodeMap>
deba@433
  1163
    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
deba@433
  1164
    public:
deba@433
  1165
      typedef typename Digraph::Node Node;
deba@433
  1166
      typedef typename Digraph::Arc edge;
deba@433
  1167
deba@433
  1168
      TopologicalSortVisitor(IntNodeMap& order, int num)
deba@433
  1169
        : _order(order), _num(num) {}
deba@433
  1170
deba@433
  1171
      void leave(const Node& node) {
deba@433
  1172
        _order.set(node, --_num);
deba@433
  1173
      }
deba@433
  1174
deba@433
  1175
    private:
deba@433
  1176
      IntNodeMap& _order;
deba@433
  1177
      int _num;
deba@433
  1178
    };
deba@433
  1179
deba@433
  1180
  }
deba@433
  1181
deba@433
  1182
  /// \ingroup connectivity
deba@433
  1183
  ///
deba@433
  1184
  /// \brief Sort the nodes of a DAG into topolgical order.
deba@433
  1185
  ///
deba@433
  1186
  /// Sort the nodes of a DAG into topolgical order.
deba@433
  1187
  ///
deba@433
  1188
  /// \param graph The graph. It must be directed and acyclic.
deba@433
  1189
  /// \retval order A writable node map. The values will be set from 0 to
deba@433
  1190
  /// the number of the nodes in the graph minus one. Each values of the map
deba@433
  1191
  /// will be set exactly once, the values  will be set descending order.
deba@433
  1192
  ///
deba@433
  1193
  /// \see checkedTopologicalSort
deba@433
  1194
  /// \see dag
deba@433
  1195
  template <typename Digraph, typename NodeMap>
deba@433
  1196
  void topologicalSort(const Digraph& graph, NodeMap& order) {
deba@435
  1197
    using namespace _connectivity_bits;
deba@433
  1198
deba@433
  1199
    checkConcept<concepts::Digraph, Digraph>();
deba@433
  1200
    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
deba@433
  1201
deba@433
  1202
    typedef typename Digraph::Node Node;
deba@433
  1203
    typedef typename Digraph::NodeIt NodeIt;
deba@433
  1204
    typedef typename Digraph::Arc Arc;
deba@433
  1205
deba@433
  1206
    TopologicalSortVisitor<Digraph, NodeMap>
deba@433
  1207
      visitor(order, countNodes(graph));
deba@433
  1208
deba@433
  1209
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
deba@433
  1210
      dfs(graph, visitor);
deba@433
  1211
deba@433
  1212
    dfs.init();
deba@433
  1213
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
  1214
      if (!dfs.reached(it)) {
deba@433
  1215
        dfs.addSource(it);
deba@433
  1216
        dfs.start();
deba@433
  1217
      }
deba@433
  1218
    }
deba@433
  1219
  }
deba@433
  1220
deba@433
  1221
  /// \ingroup connectivity
deba@433
  1222
  ///
deba@433
  1223
  /// \brief Sort the nodes of a DAG into topolgical order.
deba@433
  1224
  ///
deba@433
  1225
  /// Sort the nodes of a DAG into topolgical order. It also checks
deba@433
  1226
  /// that the given graph is DAG.
deba@433
  1227
  ///
deba@444
  1228
  /// \param digraph The graph. It must be directed and acyclic.
deba@433
  1229
  /// \retval order A readable - writable node map. The values will be set
deba@433
  1230
  /// from 0 to the number of the nodes in the graph minus one. Each values
deba@433
  1231
  /// of the map will be set exactly once, the values will be set descending
deba@433
  1232
  /// order.
kpeter@606
  1233
  /// \return \c false when the graph is not DAG.
deba@433
  1234
  ///
deba@433
  1235
  /// \see topologicalSort
deba@433
  1236
  /// \see dag
deba@433
  1237
  template <typename Digraph, typename NodeMap>
deba@435
  1238
  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
deba@435
  1239
    using namespace _connectivity_bits;
deba@433
  1240
deba@433
  1241
    checkConcept<concepts::Digraph, Digraph>();
deba@433
  1242
    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
deba@433
  1243
      NodeMap>();
deba@433
  1244
deba@433
  1245
    typedef typename Digraph::Node Node;
deba@433
  1246
    typedef typename Digraph::NodeIt NodeIt;
deba@433
  1247
    typedef typename Digraph::Arc Arc;
deba@433
  1248
deba@435
  1249
    for (NodeIt it(digraph); it != INVALID; ++it) {
deba@435
  1250
      order.set(it, -1);
deba@435
  1251
    }
deba@433
  1252
deba@433
  1253
    TopologicalSortVisitor<Digraph, NodeMap>
deba@435
  1254
      visitor(order, countNodes(digraph));
deba@433
  1255
deba@433
  1256
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
deba@435
  1257
      dfs(digraph, visitor);
deba@433
  1258
deba@433
  1259
    dfs.init();
deba@435
  1260
    for (NodeIt it(digraph); it != INVALID; ++it) {
deba@433
  1261
      if (!dfs.reached(it)) {
deba@433
  1262
        dfs.addSource(it);
deba@433
  1263
        while (!dfs.emptyQueue()) {
deba@435
  1264
           Arc arc = dfs.nextArc();
deba@435
  1265
           Node target = digraph.target(arc);
deba@433
  1266
           if (dfs.reached(target) && order[target] == -1) {
deba@433
  1267
             return false;
deba@433
  1268
           }
deba@433
  1269
           dfs.processNextArc();
deba@433
  1270
         }
deba@433
  1271
      }
deba@433
  1272
    }
deba@433
  1273
    return true;
deba@433
  1274
  }
deba@433
  1275
deba@433
  1276
  /// \ingroup connectivity
deba@433
  1277
  ///
deba@433
  1278
  /// \brief Check that the given directed graph is a DAG.
deba@433
  1279
  ///
deba@433
  1280
  /// Check that the given directed graph is a DAG. The DAG is
deba@433
  1281
  /// an Directed Acyclic Digraph.
kpeter@606
  1282
  /// \return \c false when the graph is not DAG.
deba@433
  1283
  /// \see acyclic
deba@433
  1284
  template <typename Digraph>
deba@435
  1285
  bool dag(const Digraph& digraph) {
deba@433
  1286
deba@433
  1287
    checkConcept<concepts::Digraph, Digraph>();
deba@433
  1288
deba@433
  1289
    typedef typename Digraph::Node Node;
deba@433
  1290
    typedef typename Digraph::NodeIt NodeIt;
deba@433
  1291
    typedef typename Digraph::Arc Arc;
deba@433
  1292
deba@433
  1293
    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
deba@433
  1294
deba@433
  1295
    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
deba@435
  1296
      Create dfs(digraph);
deba@433
  1297
deba@435
  1298
    ProcessedMap processed(digraph);
deba@433
  1299
    dfs.processedMap(processed);
deba@433
  1300
deba@433
  1301
    dfs.init();
deba@435
  1302
    for (NodeIt it(digraph); it != INVALID; ++it) {
deba@433
  1303
      if (!dfs.reached(it)) {
deba@433
  1304
        dfs.addSource(it);
deba@433
  1305
        while (!dfs.emptyQueue()) {
deba@433
  1306
          Arc edge = dfs.nextArc();
deba@435
  1307
          Node target = digraph.target(edge);
deba@433
  1308
          if (dfs.reached(target) && !processed[target]) {
deba@433
  1309
            return false;
deba@433
  1310
          }
deba@433
  1311
          dfs.processNextArc();
deba@433
  1312
        }
deba@433
  1313
      }
deba@433
  1314
    }
deba@433
  1315
    return true;
deba@433
  1316
  }
deba@433
  1317
deba@433
  1318
  /// \ingroup connectivity
deba@433
  1319
  ///
deba@433
  1320
  /// \brief Check that the given undirected graph is acyclic.
deba@433
  1321
  ///
deba@433
  1322
  /// Check that the given undirected graph acyclic.
deba@433
  1323
  /// \param graph The undirected graph.
kpeter@606
  1324
  /// \return \c true when there is no circle in the graph.
deba@433
  1325
  /// \see dag
deba@433
  1326
  template <typename Graph>
deba@433
  1327
  bool acyclic(const Graph& graph) {
deba@433
  1328
    checkConcept<concepts::Graph, Graph>();
deba@433
  1329
    typedef typename Graph::Node Node;
deba@433
  1330
    typedef typename Graph::NodeIt NodeIt;
deba@433
  1331
    typedef typename Graph::Arc Arc;
deba@433
  1332
    Dfs<Graph> dfs(graph);
deba@433
  1333
    dfs.init();
deba@433
  1334
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
  1335
      if (!dfs.reached(it)) {
deba@433
  1336
        dfs.addSource(it);
deba@433
  1337
        while (!dfs.emptyQueue()) {
deba@433
  1338
          Arc edge = dfs.nextArc();
deba@433
  1339
          Node source = graph.source(edge);
deba@433
  1340
          Node target = graph.target(edge);
deba@433
  1341
          if (dfs.reached(target) &&
deba@433
  1342
              dfs.predArc(source) != graph.oppositeArc(edge)) {
deba@433
  1343
            return false;
deba@433
  1344
          }
deba@433
  1345
          dfs.processNextArc();
deba@433
  1346
        }
deba@433
  1347
      }
deba@433
  1348
    }
deba@433
  1349
    return true;
deba@433
  1350
  }
deba@433
  1351
deba@433
  1352
  /// \ingroup connectivity
deba@433
  1353
  ///
deba@433
  1354
  /// \brief Check that the given undirected graph is tree.
deba@433
  1355
  ///
deba@433
  1356
  /// Check that the given undirected graph is tree.
deba@433
  1357
  /// \param graph The undirected graph.
kpeter@606
  1358
  /// \return \c true when the graph is acyclic and connected.
deba@433
  1359
  template <typename Graph>
deba@433
  1360
  bool tree(const Graph& graph) {
deba@433
  1361
    checkConcept<concepts::Graph, Graph>();
deba@433
  1362
    typedef typename Graph::Node Node;
deba@433
  1363
    typedef typename Graph::NodeIt NodeIt;
deba@433
  1364
    typedef typename Graph::Arc Arc;
deba@433
  1365
    Dfs<Graph> dfs(graph);
deba@433
  1366
    dfs.init();
deba@433
  1367
    dfs.addSource(NodeIt(graph));
deba@433
  1368
    while (!dfs.emptyQueue()) {
deba@433
  1369
      Arc edge = dfs.nextArc();
deba@433
  1370
      Node source = graph.source(edge);
deba@433
  1371
      Node target = graph.target(edge);
deba@433
  1372
      if (dfs.reached(target) &&
deba@433
  1373
          dfs.predArc(source) != graph.oppositeArc(edge)) {
deba@433
  1374
        return false;
deba@433
  1375
      }
deba@433
  1376
      dfs.processNextArc();
deba@433
  1377
    }
deba@433
  1378
    for (NodeIt it(graph); it != INVALID; ++it) {
deba@433
  1379
      if (!dfs.reached(it)) {
deba@433
  1380
        return false;
deba@433
  1381
      }
deba@433
  1382
    }
deba@433
  1383
    return true;
deba@433
  1384
  }
deba@433
  1385
deba@435
  1386
  namespace _connectivity_bits {
deba@433
  1387
deba@433
  1388
    template <typename Digraph>
deba@433
  1389
    class BipartiteVisitor : public BfsVisitor<Digraph> {
deba@433
  1390
    public:
deba@433
  1391
      typedef typename Digraph::Arc Arc;
deba@433
  1392
      typedef typename Digraph::Node Node;
deba@433
  1393
deba@433
  1394
      BipartiteVisitor(const Digraph& graph, bool& bipartite)
deba@433
  1395
        : _graph(graph), _part(graph), _bipartite(bipartite) {}
deba@433
  1396
deba@433
  1397
      void start(const Node& node) {
deba@433
  1398
        _part[node] = true;
deba@433
  1399
      }
deba@433
  1400
      void discover(const Arc& edge) {
deba@433
  1401
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
deba@433
  1402
      }
deba@433
  1403
      void examine(const Arc& edge) {
deba@433
  1404
        _bipartite = _bipartite &&
deba@433
  1405
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
deba@433
  1406
      }
deba@433
  1407
deba@433
  1408
    private:
deba@433
  1409
deba@433
  1410
      const Digraph& _graph;
deba@433
  1411
      typename Digraph::template NodeMap<bool> _part;
deba@433
  1412
      bool& _bipartite;
deba@433
  1413
    };
deba@433
  1414
deba@433
  1415
    template <typename Digraph, typename PartMap>
deba@433
  1416
    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
deba@433
  1417
    public:
deba@433
  1418
      typedef typename Digraph::Arc Arc;
deba@433
  1419
      typedef typename Digraph::Node Node;
deba@433
  1420
deba@433
  1421
      BipartitePartitionsVisitor(const Digraph& graph,
deba@433
  1422
                                 PartMap& part, bool& bipartite)
deba@433
  1423
        : _graph(graph), _part(part), _bipartite(bipartite) {}
deba@433
  1424
deba@433
  1425
      void start(const Node& node) {
deba@433
  1426
        _part.set(node, true);
deba@433
  1427
      }
deba@433
  1428
      void discover(const Arc& edge) {
deba@433
  1429
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
deba@433
  1430
      }
deba@433
  1431
      void examine(const Arc& edge) {
deba@433
  1432
        _bipartite = _bipartite &&
deba@433
  1433
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
deba@433
  1434
      }
deba@433
  1435
deba@433
  1436
    private:
deba@433
  1437
deba@433
  1438
      const Digraph& _graph;
deba@433
  1439
      PartMap& _part;
deba@433
  1440
      bool& _bipartite;
deba@433
  1441
    };
deba@433
  1442
  }
deba@433
  1443
deba@433
  1444
  /// \ingroup connectivity
deba@433
  1445
  ///
deba@433
  1446
  /// \brief Check if the given undirected graph is bipartite or not
deba@433
  1447
  ///
deba@433
  1448
  /// The function checks if the given undirected \c graph graph is bipartite
deba@433
  1449
  /// or not. The \ref Bfs algorithm is used to calculate the result.
deba@433
  1450
  /// \param graph The undirected graph.
kpeter@606
  1451
  /// \return \c true if \c graph is bipartite, \c false otherwise.
deba@433
  1452
  /// \sa bipartitePartitions
deba@433
  1453
  template<typename Graph>
deba@433
  1454
  inline bool bipartite(const Graph &graph){
deba@435
  1455
    using namespace _connectivity_bits;
deba@433
  1456
deba@433
  1457
    checkConcept<concepts::Graph, Graph>();
deba@433
  1458
deba@433
  1459
    typedef typename Graph::NodeIt NodeIt;
deba@433
  1460
    typedef typename Graph::ArcIt ArcIt;
deba@433
  1461
deba@433
  1462
    bool bipartite = true;
deba@433
  1463
deba@433
  1464
    BipartiteVisitor<Graph>
deba@433
  1465
      visitor(graph, bipartite);
deba@433
  1466
    BfsVisit<Graph, BipartiteVisitor<Graph> >
deba@433
  1467
      bfs(graph, visitor);
deba@433
  1468
    bfs.init();
deba@433
  1469
    for(NodeIt it(graph); it != INVALID; ++it) {
deba@433
  1470
      if(!bfs.reached(it)){
deba@433
  1471
        bfs.addSource(it);
deba@433
  1472
        while (!bfs.emptyQueue()) {
deba@433
  1473
          bfs.processNextNode();
deba@433
  1474
          if (!bipartite) return false;
deba@433
  1475
        }
deba@433
  1476
      }
deba@433
  1477
    }
deba@433
  1478
    return true;
deba@433
  1479
  }
deba@433
  1480
deba@433
  1481
  /// \ingroup connectivity
deba@433
  1482
  ///
deba@433
  1483
  /// \brief Check if the given undirected graph is bipartite or not
deba@433
  1484
  ///
deba@433
  1485
  /// The function checks if the given undirected graph is bipartite
deba@433
  1486
  /// or not. The  \ref  Bfs  algorithm  is   used  to  calculate the result.
deba@433
  1487
  /// During the execution, the \c partMap will be set as the two
deba@433
  1488
  /// partitions of the graph.
deba@433
  1489
  /// \param graph The undirected graph.
deba@433
  1490
  /// \retval partMap A writable bool map of nodes. It will be set as the
deba@433
  1491
  /// two partitions of the graph.
kpeter@606
  1492
  /// \return \c true if \c graph is bipartite, \c false otherwise.
deba@433
  1493
  template<typename Graph, typename NodeMap>
deba@433
  1494
  inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
deba@435
  1495
    using namespace _connectivity_bits;
deba@433
  1496
deba@433
  1497
    checkConcept<concepts::Graph, Graph>();
deba@433
  1498
deba@433
  1499
    typedef typename Graph::Node Node;
deba@433
  1500
    typedef typename Graph::NodeIt NodeIt;
deba@433
  1501
    typedef typename Graph::ArcIt ArcIt;
deba@433
  1502
deba@433
  1503
    bool bipartite = true;
deba@433
  1504
deba@433
  1505
    BipartitePartitionsVisitor<Graph, NodeMap>
deba@433
  1506
      visitor(graph, partMap, bipartite);
deba@433
  1507
    BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
deba@433
  1508
      bfs(graph, visitor);
deba@433
  1509
    bfs.init();
deba@433
  1510
    for(NodeIt it(graph); it != INVALID; ++it) {
deba@433
  1511
      if(!bfs.reached(it)){
deba@433
  1512
        bfs.addSource(it);
deba@433
  1513
        while (!bfs.emptyQueue()) {
deba@433
  1514
          bfs.processNextNode();
deba@433
  1515
          if (!bipartite) return false;
deba@433
  1516
        }
deba@433
  1517
      }
deba@433
  1518
    }
deba@433
  1519
    return true;
deba@433
  1520
  }
deba@433
  1521
deba@433
  1522
  /// \brief Returns true when there are not loop edges in the graph.
deba@433
  1523
  ///
deba@433
  1524
  /// Returns true when there are not loop edges in the graph.
deba@433
  1525
  template <typename Digraph>
deba@435
  1526
  bool loopFree(const Digraph& digraph) {
deba@435
  1527
    for (typename Digraph::ArcIt it(digraph); it != INVALID; ++it) {
deba@435
  1528
      if (digraph.source(it) == digraph.target(it)) return false;
deba@433
  1529
    }
deba@433
  1530
    return true;
deba@433
  1531
  }
deba@433
  1532
deba@433
  1533
  /// \brief Returns true when there are not parallel edges in the graph.
deba@433
  1534
  ///
deba@433
  1535
  /// Returns true when there are not parallel edges in the graph.
deba@433
  1536
  template <typename Digraph>
deba@435
  1537
  bool parallelFree(const Digraph& digraph) {
deba@435
  1538
    typename Digraph::template NodeMap<bool> reached(digraph, false);
deba@435
  1539
    for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
deba@435
  1540
      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
deba@435
  1541
        if (reached[digraph.target(a)]) return false;
deba@435
  1542
        reached.set(digraph.target(a), true);
deba@433
  1543
      }
deba@435
  1544
      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
deba@435
  1545
        reached.set(digraph.target(a), false);
deba@433
  1546
      }
deba@433
  1547
    }
deba@433
  1548
    return true;
deba@433
  1549
  }
deba@433
  1550
deba@433
  1551
  /// \brief Returns true when there are not loop edges and parallel
deba@433
  1552
  /// edges in the graph.
deba@433
  1553
  ///
deba@433
  1554
  /// Returns true when there are not loop edges and parallel edges in
deba@433
  1555
  /// the graph.
deba@433
  1556
  template <typename Digraph>
deba@435
  1557
  bool simpleDigraph(const Digraph& digraph) {
deba@435
  1558
    typename Digraph::template NodeMap<bool> reached(digraph, false);
deba@435
  1559
    for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
deba@433
  1560
      reached.set(n, true);
deba@435
  1561
      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
deba@435
  1562
        if (reached[digraph.target(a)]) return false;
deba@435
  1563
        reached.set(digraph.target(a), true);
deba@433
  1564
      }
deba@435
  1565
      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
deba@435
  1566
        reached.set(digraph.target(a), false);
deba@433
  1567
      }
deba@433
  1568
      reached.set(n, false);
deba@433
  1569
    }
deba@433
  1570
    return true;
deba@433
  1571
  }
deba@433
  1572
deba@433
  1573
} //namespace lemon
deba@433
  1574
deba@435
  1575
#endif //LEMON_CONNECTIVITY_H