lemon/connectivity.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 24 Mar 2009 00:18:25 +0100
changeset 596 8c3112a66878
parent 425 cace3206223b
child 550 c5fd2d996909
permissions -rw-r--r--
Use XTI implementation instead of ATI in NetworkSimplex (#234)

XTI (eXtended Threaded Index) is an imporved version of the widely
known ATI (Augmented Threaded Index) method for storing and updating
the spanning tree structure in Network Simplex algorithms.

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