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