gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Port topology.h as connectivity.h from SVN -r3509 (#61)
0 0 1
default
1 file changed with 1572 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#ifndef LEMON_TOPOLOGY_H
20
#define LEMON_TOPOLOGY_H
21

	
22
#include <lemon/dfs.h>
23
#include <lemon/bfs.h>
24
#include <lemon/core.h>
25
#include <lemon/maps.h>
26
#include <lemon/adaptors.h>
27

	
28
#include <lemon/concepts/digraph.h>
29
#include <lemon/concepts/graph.h>
30
#include <lemon/concept_check.h>
31

	
32
#include <stack>
33
#include <functional>
34

	
35
/// \ingroup connectivity
36
/// \file
37
/// \brief Connectivity algorithms
38
///
39
/// Connectivity algorithms
40

	
41
namespace lemon {
42

	
43
  /// \ingroup connectivity
44
  ///
45
  /// \brief Check whether the given undirected graph is connected.
46
  ///
47
  /// Check whether the given undirected graph is connected.
48
  /// \param graph The undirected graph.
49
  /// \return %True when there is path between any two nodes in the graph.
50
  /// \note By definition, the empty graph is connected.
51
  template <typename Graph>
52
  bool connected(const Graph& graph) {
53
    checkConcept<concepts::Graph, Graph>();
54
    typedef typename Graph::NodeIt NodeIt;
55
    if (NodeIt(graph) == INVALID) return true;
56
    Dfs<Graph> dfs(graph);
57
    dfs.run(NodeIt(graph));
58
    for (NodeIt it(graph); it != INVALID; ++it) {
59
      if (!dfs.reached(it)) {
60
        return false;
61
      }
62
    }
63
    return true;
64
  }
65

	
66
  /// \ingroup connectivity
67
  ///
68
  /// \brief Count the number of connected components of an undirected graph
69
  ///
70
  /// Count the number of connected components of an undirected graph
71
  ///
72
  /// \param graph The graph. It must be undirected.
73
  /// \return The number of components
74
  /// \note By definition, the empty graph consists
75
  /// of zero connected components.
76
  template <typename Graph>
77
  int countConnectedComponents(const Graph &graph) {
78
    checkConcept<concepts::Graph, Graph>();
79
    typedef typename Graph::Node Node;
80
    typedef typename Graph::Arc Arc;
81

	
82
    typedef NullMap<Node, Arc> PredMap;
83
    typedef NullMap<Node, int> DistMap;
84

	
85
    int compNum = 0;
86
    typename Bfs<Graph>::
87
      template SetPredMap<PredMap>::
88
      template SetDistMap<DistMap>::
89
      Create bfs(graph);
90

	
91
    PredMap predMap;
92
    bfs.predMap(predMap);
93

	
94
    DistMap distMap;
95
    bfs.distMap(distMap);
96

	
97
    bfs.init();
98
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
99
      if (!bfs.reached(n)) {
100
        bfs.addSource(n);
101
        bfs.start();
102
        ++compNum;
103
      }
104
    }
105
    return compNum;
106
  }
107

	
108
  /// \ingroup connectivity
109
  ///
110
  /// \brief Find the connected components of an undirected graph
111
  ///
112
  /// Find the connected components of an undirected graph.
113
  ///
114
  /// \param graph The graph. It must be undirected.
115
  /// \retval compMap A writable node map. The values will be set from 0 to
116
  /// the number of the connected components minus one. Each values of the map
117
  /// will be set exactly once, the values of a certain component will be
118
  /// set continuously.
119
  /// \return The number of components
120
  ///
121
  template <class Graph, class NodeMap>
122
  int connectedComponents(const Graph &graph, NodeMap &compMap) {
123
    checkConcept<concepts::Graph, Graph>();
124
    typedef typename Graph::Node Node;
125
    typedef typename Graph::Arc Arc;
126
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
127

	
128
    typedef NullMap<Node, Arc> PredMap;
129
    typedef NullMap<Node, int> DistMap;
130

	
131
    int compNum = 0;
132
    typename Bfs<Graph>::
133
      template SetPredMap<PredMap>::
134
      template SetDistMap<DistMap>::
135
      Create bfs(graph);
136

	
137
    PredMap predMap;
138
    bfs.predMap(predMap);
139

	
140
    DistMap distMap;
141
    bfs.distMap(distMap);
142

	
143
    bfs.init();
144
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
145
      if(!bfs.reached(n)) {
146
        bfs.addSource(n);
147
        while (!bfs.emptyQueue()) {
148
          compMap.set(bfs.nextNode(), compNum);
149
          bfs.processNextNode();
150
        }
151
        ++compNum;
152
      }
153
    }
154
    return compNum;
155
  }
156

	
157
  namespace _topology_bits {
158

	
159
    template <typename Digraph, typename Iterator >
160
    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
161
    public:
162
      typedef typename Digraph::Node Node;
163
      LeaveOrderVisitor(Iterator it) : _it(it) {}
164

	
165
      void leave(const Node& node) {
166
        *(_it++) = node;
167
      }
168

	
169
    private:
170
      Iterator _it;
171
    };
172

	
173
    template <typename Digraph, typename Map>
174
    struct FillMapVisitor : public DfsVisitor<Digraph> {
175
    public:
176
      typedef typename Digraph::Node Node;
177
      typedef typename Map::Value Value;
178

	
179
      FillMapVisitor(Map& map, Value& value)
180
        : _map(map), _value(value) {}
181

	
182
      void reach(const Node& node) {
183
        _map.set(node, _value);
184
      }
185
    private:
186
      Map& _map;
187
      Value& _value;
188
    };
189

	
190
    template <typename Digraph, typename ArcMap>
191
    struct StronglyConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
192
    public:
193
      typedef typename Digraph::Node Node;
194
      typedef typename Digraph::Arc Arc;
195

	
196
      StronglyConnectedCutEdgesVisitor(const Digraph& digraph,
197
                                       ArcMap& cutMap,
198
                                       int& cutNum)
199
        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
200
          _compMap(digraph), _num(0) {
201
      }
202

	
203
      void stop(const Node&) {
204
        ++_num;
205
      }
206

	
207
      void reach(const Node& node) {
208
        _compMap.set(node, _num);
209
      }
210

	
211
      void examine(const Arc& arc) {
212
         if (_compMap[_digraph.source(arc)] !=
213
             _compMap[_digraph.target(arc)]) {
214
           _cutMap.set(arc, true);
215
           ++_cutNum;
216
         }
217
      }
218
    private:
219
      const Digraph& _digraph;
220
      ArcMap& _cutMap;
221
      int& _cutNum;
222

	
223
      typename Digraph::template NodeMap<int> _compMap;
224
      int _num;
225
    };
226

	
227
  }
228

	
229

	
230
  /// \ingroup connectivity
231
  ///
232
  /// \brief Check whether the given directed graph is strongly connected.
233
  ///
234
  /// Check whether the given directed graph is strongly connected. The
235
  /// graph is strongly connected when any two nodes of the graph are
236
  /// connected with directed paths in both direction.
237
  /// \return %False when the graph is not strongly connected.
238
  /// \see connected
239
  ///
240
  /// \note By definition, the empty graph is strongly connected.
241
  template <typename Digraph>
242
  bool stronglyConnected(const Digraph& digraph) {
243
    checkConcept<concepts::Digraph, Digraph>();
244

	
245
    typedef typename Digraph::Node Node;
246
    typedef typename Digraph::NodeIt NodeIt;
247

	
248
    typename Digraph::Node source = NodeIt(digraph);
249
    if (source == INVALID) return true;
250

	
251
    using namespace _topology_bits;
252

	
253
    typedef DfsVisitor<Digraph> Visitor;
254
    Visitor visitor;
255

	
256
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
257
    dfs.init();
258
    dfs.addSource(source);
259
    dfs.start();
260

	
261
    for (NodeIt it(digraph); it != INVALID; ++it) {
262
      if (!dfs.reached(it)) {
263
        return false;
264
      }
265
    }
266

	
267
    typedef ReverseDigraph<const Digraph> RDigraph;
268
    RDigraph rdigraph(digraph);
269

	
270
    typedef DfsVisitor<Digraph> RVisitor;
271
    RVisitor rvisitor;
272

	
273
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
274
    rdfs.init();
275
    rdfs.addSource(source);
276
    rdfs.start();
277

	
278
    for (NodeIt it(rdigraph); it != INVALID; ++it) {
279
      if (!rdfs.reached(it)) {
280
        return false;
281
      }
282
    }
283

	
284
    return true;
285
  }
286

	
287
  /// \ingroup connectivity
288
  ///
289
  /// \brief Count the strongly connected components of a directed graph
290
  ///
291
  /// Count the strongly connected components of a directed graph.
292
  /// The strongly connected components are the classes of an
293
  /// equivalence relation on the nodes of the graph. Two nodes are in
294
  /// the same class if they are connected with directed paths in both
295
  /// direction.
296
  ///
297
  /// \param graph The graph.
298
  /// \return The number of components
299
  /// \note By definition, the empty graph has zero
300
  /// strongly connected components.
301
  template <typename Digraph>
302
  int countStronglyConnectedComponents(const Digraph& digraph) {
303
    checkConcept<concepts::Digraph, Digraph>();
304

	
305
    using namespace _topology_bits;
306

	
307
    typedef typename Digraph::Node Node;
308
    typedef typename Digraph::Arc Arc;
309
    typedef typename Digraph::NodeIt NodeIt;
310
    typedef typename Digraph::ArcIt ArcIt;
311

	
312
    typedef std::vector<Node> Container;
313
    typedef typename Container::iterator Iterator;
314

	
315
    Container nodes(countNodes(digraph));
316
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
317
    Visitor visitor(nodes.begin());
318

	
319
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
320
    dfs.init();
321
    for (NodeIt it(digraph); it != INVALID; ++it) {
322
      if (!dfs.reached(it)) {
323
        dfs.addSource(it);
324
        dfs.start();
325
      }
326
    }
327

	
328
    typedef typename Container::reverse_iterator RIterator;
329
    typedef ReverseDigraph<const Digraph> RDigraph;
330

	
331
    RDigraph rdigraph(digraph);
332

	
333
    typedef DfsVisitor<Digraph> RVisitor;
334
    RVisitor rvisitor;
335

	
336
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
337

	
338
    int compNum = 0;
339

	
340
    rdfs.init();
341
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
342
      if (!rdfs.reached(*it)) {
343
        rdfs.addSource(*it);
344
        rdfs.start();
345
        ++compNum;
346
      }
347
    }
348
    return compNum;
349
  }
350

	
351
  /// \ingroup connectivity
352
  ///
353
  /// \brief Find the strongly connected components of a directed graph
354
  ///
355
  /// Find the strongly connected components of a directed graph.  The
356
  /// strongly connected components are the classes of an equivalence
357
  /// relation on the nodes of the graph. Two nodes are in
358
  /// relationship when there are directed paths between them in both
359
  /// direction. In addition, the numbering of components will satisfy
360
  /// that there is no arc going from a higher numbered component to
361
  /// a lower.
362
  ///
363
  /// \param digraph The digraph.
364
  /// \retval compMap A writable node map. The values will be set from 0 to
365
  /// the number of the strongly connected components minus one. Each value
366
  /// of the map will be set exactly once, the values of a certain component
367
  /// will be set continuously.
368
  /// \return The number of components
369
  ///
370
  template <typename Digraph, typename NodeMap>
371
  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
372
    checkConcept<concepts::Digraph, Digraph>();
373
    typedef typename Digraph::Node Node;
374
    typedef typename Digraph::NodeIt NodeIt;
375
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
376

	
377
    using namespace _topology_bits;
378

	
379
    typedef std::vector<Node> Container;
380
    typedef typename Container::iterator Iterator;
381

	
382
    Container nodes(countNodes(digraph));
383
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
384
    Visitor visitor(nodes.begin());
385

	
386
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
387
    dfs.init();
388
    for (NodeIt it(digraph); it != INVALID; ++it) {
389
      if (!dfs.reached(it)) {
390
        dfs.addSource(it);
391
        dfs.start();
392
      }
393
    }
394

	
395
    typedef typename Container::reverse_iterator RIterator;
396
    typedef ReverseDigraph<const Digraph> RDigraph;
397

	
398
    RDigraph rdigraph(digraph);
399

	
400
    int compNum = 0;
401

	
402
    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
403
    RVisitor rvisitor(compMap, compNum);
404

	
405
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
406

	
407
    rdfs.init();
408
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
409
      if (!rdfs.reached(*it)) {
410
        rdfs.addSource(*it);
411
        rdfs.start();
412
        ++compNum;
413
      }
414
    }
415
    return compNum;
416
  }
417

	
418
  /// \ingroup connectivity
419
  ///
420
  /// \brief Find the cut arcs of the strongly connected components.
421
  ///
422
  /// Find the cut arcs of the strongly connected components.
423
  /// The strongly connected components are the classes of an equivalence
424
  /// relation on the nodes of the graph. Two nodes are in relationship
425
  /// when there are directed paths between them in both direction.
426
  /// The strongly connected components are separated by the cut arcs.
427
  ///
428
  /// \param graph The graph.
429
  /// \retval cutMap A writable node map. The values will be set true when the
430
  /// arc is a cut arc.
431
  ///
432
  /// \return The number of cut arcs
433
  template <typename Digraph, typename ArcMap>
434
  int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
435
    checkConcept<concepts::Digraph, Digraph>();
436
    typedef typename Digraph::Node Node;
437
    typedef typename Digraph::Arc Arc;
438
    typedef typename Digraph::NodeIt NodeIt;
439
    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
440

	
441
    using namespace _topology_bits;
442

	
443
    typedef std::vector<Node> Container;
444
    typedef typename Container::iterator Iterator;
445

	
446
    Container nodes(countNodes(graph));
447
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
448
    Visitor visitor(nodes.begin());
449

	
450
    DfsVisit<Digraph, Visitor> dfs(graph, visitor);
451
    dfs.init();
452
    for (NodeIt it(graph); it != INVALID; ++it) {
453
      if (!dfs.reached(it)) {
454
        dfs.addSource(it);
455
        dfs.start();
456
      }
457
    }
458

	
459
    typedef typename Container::reverse_iterator RIterator;
460
    typedef ReverseDigraph<const Digraph> RDigraph;
461

	
462
    RDigraph rgraph(graph);
463

	
464
    int cutNum = 0;
465

	
466
    typedef StronglyConnectedCutEdgesVisitor<RDigraph, ArcMap> RVisitor;
467
    RVisitor rvisitor(rgraph, cutMap, cutNum);
468

	
469
    DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
470

	
471
    rdfs.init();
472
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
473
      if (!rdfs.reached(*it)) {
474
        rdfs.addSource(*it);
475
        rdfs.start();
476
      }
477
    }
478
    return cutNum;
479
  }
480

	
481
  namespace _topology_bits {
482

	
483
    template <typename Digraph>
484
    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
485
    public:
486
      typedef typename Digraph::Node Node;
487
      typedef typename Digraph::Arc Arc;
488
      typedef typename Digraph::Edge Edge;
489

	
490
      CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
491
        : _graph(graph), _compNum(compNum),
492
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
493

	
494
      void start(const Node& node) {
495
        _predMap.set(node, INVALID);
496
      }
497

	
498
      void reach(const Node& node) {
499
        _numMap.set(node, _num);
500
        _retMap.set(node, _num);
501
        ++_num;
502
      }
503

	
504
      void discover(const Arc& edge) {
505
        _predMap.set(_graph.target(edge), _graph.source(edge));
506
      }
507

	
508
      void examine(const Arc& edge) {
509
        if (_graph.source(edge) == _graph.target(edge) &&
510
            _graph.direction(edge)) {
511
          ++_compNum;
512
          return;
513
        }
514
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
515
          return;
516
        }
517
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
518
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
519
        }
520
      }
521

	
522
      void backtrack(const Arc& edge) {
523
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
524
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
525
        }
526
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
527
          ++_compNum;
528
        }
529
      }
530

	
531
    private:
532
      const Digraph& _graph;
533
      int& _compNum;
534

	
535
      typename Digraph::template NodeMap<int> _numMap;
536
      typename Digraph::template NodeMap<int> _retMap;
537
      typename Digraph::template NodeMap<Node> _predMap;
538
      int _num;
539
    };
540

	
541
    template <typename Digraph, typename ArcMap>
542
    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
543
    public:
544
      typedef typename Digraph::Node Node;
545
      typedef typename Digraph::Arc Arc;
546
      typedef typename Digraph::Edge Edge;
547

	
548
      BiNodeConnectedComponentsVisitor(const Digraph& graph,
549
                                       ArcMap& compMap, int &compNum)
550
        : _graph(graph), _compMap(compMap), _compNum(compNum),
551
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
552

	
553
      void start(const Node& node) {
554
        _predMap.set(node, INVALID);
555
      }
556

	
557
      void reach(const Node& node) {
558
        _numMap.set(node, _num);
559
        _retMap.set(node, _num);
560
        ++_num;
561
      }
562

	
563
      void discover(const Arc& edge) {
564
        Node target = _graph.target(edge);
565
        _predMap.set(target, edge);
566
        _edgeStack.push(edge);
567
      }
568

	
569
      void examine(const Arc& edge) {
570
        Node source = _graph.source(edge);
571
        Node target = _graph.target(edge);
572
        if (source == target && _graph.direction(edge)) {
573
          _compMap.set(edge, _compNum);
574
          ++_compNum;
575
          return;
576
        }
577
        if (_numMap[target] < _numMap[source]) {
578
          if (_predMap[source] != _graph.oppositeArc(edge)) {
579
            _edgeStack.push(edge);
580
          }
581
        }
582
        if (_predMap[source] != INVALID &&
583
            target == _graph.source(_predMap[source])) {
584
          return;
585
        }
586
        if (_retMap[source] > _numMap[target]) {
587
          _retMap.set(source, _numMap[target]);
588
        }
589
      }
590

	
591
      void backtrack(const Arc& edge) {
592
        Node source = _graph.source(edge);
593
        Node target = _graph.target(edge);
594
        if (_retMap[source] > _retMap[target]) {
595
          _retMap.set(source, _retMap[target]);
596
        }
597
        if (_numMap[source] <= _retMap[target]) {
598
          while (_edgeStack.top() != edge) {
599
            _compMap.set(_edgeStack.top(), _compNum);
600
            _edgeStack.pop();
601
          }
602
          _compMap.set(edge, _compNum);
603
          _edgeStack.pop();
604
          ++_compNum;
605
        }
606
      }
607

	
608
    private:
609
      const Digraph& _graph;
610
      ArcMap& _compMap;
611
      int& _compNum;
612

	
613
      typename Digraph::template NodeMap<int> _numMap;
614
      typename Digraph::template NodeMap<int> _retMap;
615
      typename Digraph::template NodeMap<Arc> _predMap;
616
      std::stack<Edge> _edgeStack;
617
      int _num;
618
    };
619

	
620

	
621
    template <typename Digraph, typename NodeMap>
622
    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
623
    public:
624
      typedef typename Digraph::Node Node;
625
      typedef typename Digraph::Arc Arc;
626
      typedef typename Digraph::Edge Edge;
627

	
628
      BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
629
                                     int& cutNum)
630
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
631
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
632

	
633
      void start(const Node& node) {
634
        _predMap.set(node, INVALID);
635
        rootCut = false;
636
      }
637

	
638
      void reach(const Node& node) {
639
        _numMap.set(node, _num);
640
        _retMap.set(node, _num);
641
        ++_num;
642
      }
643

	
644
      void discover(const Arc& edge) {
645
        _predMap.set(_graph.target(edge), _graph.source(edge));
646
      }
647

	
648
      void examine(const Arc& edge) {
649
        if (_graph.source(edge) == _graph.target(edge) &&
650
            _graph.direction(edge)) {
651
          if (!_cutMap[_graph.source(edge)]) {
652
            _cutMap.set(_graph.source(edge), true);
653
            ++_cutNum;
654
          }
655
          return;
656
        }
657
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
658
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
659
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
660
        }
661
      }
662

	
663
      void backtrack(const Arc& edge) {
664
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
665
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
666
        }
667
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
668
          if (_predMap[_graph.source(edge)] != INVALID) {
669
            if (!_cutMap[_graph.source(edge)]) {
670
              _cutMap.set(_graph.source(edge), true);
671
              ++_cutNum;
672
            }
673
          } else if (rootCut) {
674
            if (!_cutMap[_graph.source(edge)]) {
675
              _cutMap.set(_graph.source(edge), true);
676
              ++_cutNum;
677
            }
678
          } else {
679
            rootCut = true;
680
          }
681
        }
682
      }
683

	
684
    private:
685
      const Digraph& _graph;
686
      NodeMap& _cutMap;
687
      int& _cutNum;
688

	
689
      typename Digraph::template NodeMap<int> _numMap;
690
      typename Digraph::template NodeMap<int> _retMap;
691
      typename Digraph::template NodeMap<Node> _predMap;
692
      std::stack<Edge> _edgeStack;
693
      int _num;
694
      bool rootCut;
695
    };
696

	
697
  }
698

	
699
  template <typename Graph>
700
  int countBiNodeConnectedComponents(const Graph& graph);
701

	
702
  /// \ingroup connectivity
703
  ///
704
  /// \brief Checks the graph is bi-node-connected.
705
  ///
706
  /// This function checks that the undirected graph is bi-node-connected
707
  /// graph. The graph is bi-node-connected if any two undirected edge is
708
  /// on same circle.
709
  ///
710
  /// \param graph The graph.
711
  /// \return %True when the graph bi-node-connected.
712
  template <typename Graph>
713
  bool biNodeConnected(const Graph& graph) {
714
    return countBiNodeConnectedComponents(graph) <= 1;
715
  }
716

	
717
  /// \ingroup connectivity
718
  ///
719
  /// \brief Count the biconnected components.
720
  ///
721
  /// This function finds the bi-node-connected components in an undirected
722
  /// graph. The biconnected components are the classes of an equivalence
723
  /// relation on the undirected edges. Two undirected edge is in relationship
724
  /// when they are on same circle.
725
  ///
726
  /// \param graph The graph.
727
  /// \return The number of components.
728
  template <typename Graph>
729
  int countBiNodeConnectedComponents(const Graph& graph) {
730
    checkConcept<concepts::Graph, Graph>();
731
    typedef typename Graph::NodeIt NodeIt;
732

	
733
    using namespace _topology_bits;
734

	
735
    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
736

	
737
    int compNum = 0;
738
    Visitor visitor(graph, compNum);
739

	
740
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
741
    dfs.init();
742

	
743
    for (NodeIt it(graph); it != INVALID; ++it) {
744
      if (!dfs.reached(it)) {
745
        dfs.addSource(it);
746
        dfs.start();
747
      }
748
    }
749
    return compNum;
750
  }
751

	
752
  /// \ingroup connectivity
753
  ///
754
  /// \brief Find the bi-node-connected components.
755
  ///
756
  /// This function finds the bi-node-connected components in an undirected
757
  /// graph. The bi-node-connected components are the classes of an equivalence
758
  /// relation on the undirected edges. Two undirected edge are in relationship
759
  /// when they are on same circle.
760
  ///
761
  /// \param graph The graph.
762
  /// \retval compMap A writable uedge map. The values will be set from 0
763
  /// to the number of the biconnected components minus one. Each values
764
  /// of the map will be set exactly once, the values of a certain component
765
  /// will be set continuously.
766
  /// \return The number of components.
767
  ///
768
  template <typename Graph, typename EdgeMap>
769
  int biNodeConnectedComponents(const Graph& graph,
770
                                EdgeMap& compMap) {
771
    checkConcept<concepts::Graph, Graph>();
772
    typedef typename Graph::NodeIt NodeIt;
773
    typedef typename Graph::Edge Edge;
774
    checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
775

	
776
    using namespace _topology_bits;
777

	
778
    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
779

	
780
    int compNum = 0;
781
    Visitor visitor(graph, compMap, compNum);
782

	
783
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
784
    dfs.init();
785

	
786
    for (NodeIt it(graph); it != INVALID; ++it) {
787
      if (!dfs.reached(it)) {
788
        dfs.addSource(it);
789
        dfs.start();
790
      }
791
    }
792
    return compNum;
793
  }
794

	
795
  /// \ingroup connectivity
796
  ///
797
  /// \brief Find the bi-node-connected cut nodes.
798
  ///
799
  /// This function finds the bi-node-connected cut nodes in an undirected
800
  /// graph. The bi-node-connected components are the classes of an equivalence
801
  /// relation on the undirected edges. Two undirected edges are in
802
  /// relationship when they are on same circle. The biconnected components
803
  /// are separted by nodes which are the cut nodes of the components.
804
  ///
805
  /// \param graph The graph.
806
  /// \retval cutMap A writable edge map. The values will be set true when
807
  /// the node separate two or more components.
808
  /// \return The number of the cut nodes.
809
  template <typename Graph, typename NodeMap>
810
  int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
811
    checkConcept<concepts::Graph, Graph>();
812
    typedef typename Graph::Node Node;
813
    typedef typename Graph::NodeIt NodeIt;
814
    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
815

	
816
    using namespace _topology_bits;
817

	
818
    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
819

	
820
    int cutNum = 0;
821
    Visitor visitor(graph, cutMap, cutNum);
822

	
823
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
824
    dfs.init();
825

	
826
    for (NodeIt it(graph); it != INVALID; ++it) {
827
      if (!dfs.reached(it)) {
828
        dfs.addSource(it);
829
        dfs.start();
830
      }
831
    }
832
    return cutNum;
833
  }
834

	
835
  namespace _topology_bits {
836

	
837
    template <typename Digraph>
838
    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
839
    public:
840
      typedef typename Digraph::Node Node;
841
      typedef typename Digraph::Arc Arc;
842
      typedef typename Digraph::Edge Edge;
843

	
844
      CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
845
        : _graph(graph), _compNum(compNum),
846
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
847

	
848
      void start(const Node& node) {
849
        _predMap.set(node, INVALID);
850
      }
851

	
852
      void reach(const Node& node) {
853
        _numMap.set(node, _num);
854
        _retMap.set(node, _num);
855
        ++_num;
856
      }
857

	
858
      void leave(const Node& node) {
859
        if (_numMap[node] <= _retMap[node]) {
860
          ++_compNum;
861
        }
862
      }
863

	
864
      void discover(const Arc& edge) {
865
        _predMap.set(_graph.target(edge), edge);
866
      }
867

	
868
      void examine(const Arc& edge) {
869
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
870
          return;
871
        }
872
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
873
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
874
        }
875
      }
876

	
877
      void backtrack(const Arc& edge) {
878
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
879
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
880
        }
881
      }
882

	
883
    private:
884
      const Digraph& _graph;
885
      int& _compNum;
886

	
887
      typename Digraph::template NodeMap<int> _numMap;
888
      typename Digraph::template NodeMap<int> _retMap;
889
      typename Digraph::template NodeMap<Arc> _predMap;
890
      int _num;
891
    };
892

	
893
    template <typename Digraph, typename NodeMap>
894
    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
895
    public:
896
      typedef typename Digraph::Node Node;
897
      typedef typename Digraph::Arc Arc;
898
      typedef typename Digraph::Edge Edge;
899

	
900
      BiEdgeConnectedComponentsVisitor(const Digraph& graph,
901
                                       NodeMap& compMap, int &compNum)
902
        : _graph(graph), _compMap(compMap), _compNum(compNum),
903
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
904

	
905
      void start(const Node& node) {
906
        _predMap.set(node, INVALID);
907
      }
908

	
909
      void reach(const Node& node) {
910
        _numMap.set(node, _num);
911
        _retMap.set(node, _num);
912
        _nodeStack.push(node);
913
        ++_num;
914
      }
915

	
916
      void leave(const Node& node) {
917
        if (_numMap[node] <= _retMap[node]) {
918
          while (_nodeStack.top() != node) {
919
            _compMap.set(_nodeStack.top(), _compNum);
920
            _nodeStack.pop();
921
          }
922
          _compMap.set(node, _compNum);
923
          _nodeStack.pop();
924
          ++_compNum;
925
        }
926
      }
927

	
928
      void discover(const Arc& edge) {
929
        _predMap.set(_graph.target(edge), edge);
930
      }
931

	
932
      void examine(const Arc& edge) {
933
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
934
          return;
935
        }
936
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
937
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
938
        }
939
      }
940

	
941
      void backtrack(const Arc& edge) {
942
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
943
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
944
        }
945
      }
946

	
947
    private:
948
      const Digraph& _graph;
949
      NodeMap& _compMap;
950
      int& _compNum;
951

	
952
      typename Digraph::template NodeMap<int> _numMap;
953
      typename Digraph::template NodeMap<int> _retMap;
954
      typename Digraph::template NodeMap<Arc> _predMap;
955
      std::stack<Node> _nodeStack;
956
      int _num;
957
    };
958

	
959

	
960
    template <typename Digraph, typename ArcMap>
961
    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
962
    public:
963
      typedef typename Digraph::Node Node;
964
      typedef typename Digraph::Arc Arc;
965
      typedef typename Digraph::Edge Edge;
966

	
967
      BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
968
                                     ArcMap& cutMap, int &cutNum)
969
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
970
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
971

	
972
      void start(const Node& node) {
973
        _predMap[node] = INVALID;
974
      }
975

	
976
      void reach(const Node& node) {
977
        _numMap.set(node, _num);
978
        _retMap.set(node, _num);
979
        ++_num;
980
      }
981

	
982
      void leave(const Node& node) {
983
        if (_numMap[node] <= _retMap[node]) {
984
          if (_predMap[node] != INVALID) {
985
            _cutMap.set(_predMap[node], true);
986
            ++_cutNum;
987
          }
988
        }
989
      }
990

	
991
      void discover(const Arc& edge) {
992
        _predMap.set(_graph.target(edge), edge);
993
      }
994

	
995
      void examine(const Arc& edge) {
996
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
997
          return;
998
        }
999
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1000
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1001
        }
1002
      }
1003

	
1004
      void backtrack(const Arc& edge) {
1005
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1006
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1007
        }
1008
      }
1009

	
1010
    private:
1011
      const Digraph& _graph;
1012
      ArcMap& _cutMap;
1013
      int& _cutNum;
1014

	
1015
      typename Digraph::template NodeMap<int> _numMap;
1016
      typename Digraph::template NodeMap<int> _retMap;
1017
      typename Digraph::template NodeMap<Arc> _predMap;
1018
      int _num;
1019
    };
1020
  }
1021

	
1022
  template <typename Graph>
1023
  int countBiEdgeConnectedComponents(const Graph& graph);
1024

	
1025
  /// \ingroup connectivity
1026
  ///
1027
  /// \brief Checks that the graph is bi-edge-connected.
1028
  ///
1029
  /// This function checks that the graph is bi-edge-connected. The undirected
1030
  /// graph is bi-edge-connected when any two nodes are connected with two
1031
  /// edge-disjoint paths.
1032
  ///
1033
  /// \param graph The undirected graph.
1034
  /// \return The number of components.
1035
  template <typename Graph>
1036
  bool biEdgeConnected(const Graph& graph) {
1037
    return countBiEdgeConnectedComponents(graph) <= 1;
1038
  }
1039

	
1040
  /// \ingroup connectivity
1041
  ///
1042
  /// \brief Count the bi-edge-connected components.
1043
  ///
1044
  /// This function count the bi-edge-connected components in an undirected
1045
  /// graph. The bi-edge-connected components are the classes of an equivalence
1046
  /// relation on the nodes. Two nodes are in relationship when they are
1047
  /// connected with at least two edge-disjoint paths.
1048
  ///
1049
  /// \param graph The undirected graph.
1050
  /// \return The number of components.
1051
  template <typename Graph>
1052
  int countBiEdgeConnectedComponents(const Graph& graph) {
1053
    checkConcept<concepts::Graph, Graph>();
1054
    typedef typename Graph::NodeIt NodeIt;
1055

	
1056
    using namespace _topology_bits;
1057

	
1058
    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1059

	
1060
    int compNum = 0;
1061
    Visitor visitor(graph, compNum);
1062

	
1063
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1064
    dfs.init();
1065

	
1066
    for (NodeIt it(graph); it != INVALID; ++it) {
1067
      if (!dfs.reached(it)) {
1068
        dfs.addSource(it);
1069
        dfs.start();
1070
      }
1071
    }
1072
    return compNum;
1073
  }
1074

	
1075
  /// \ingroup connectivity
1076
  ///
1077
  /// \brief Find the bi-edge-connected components.
1078
  ///
1079
  /// This function finds the bi-edge-connected components in an undirected
1080
  /// graph. The bi-edge-connected components are the classes of an equivalence
1081
  /// relation on the nodes. Two nodes are in relationship when they are
1082
  /// connected at least two edge-disjoint paths.
1083
  ///
1084
  /// \param graph The graph.
1085
  /// \retval compMap A writable node map. The values will be set from 0 to
1086
  /// the number of the biconnected components minus one. Each values
1087
  /// of the map will be set exactly once, the values of a certain component
1088
  /// will be set continuously.
1089
  /// \return The number of components.
1090
  ///
1091
  template <typename Graph, typename NodeMap>
1092
  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
1093
    checkConcept<concepts::Graph, Graph>();
1094
    typedef typename Graph::NodeIt NodeIt;
1095
    typedef typename Graph::Node Node;
1096
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1097

	
1098
    using namespace _topology_bits;
1099

	
1100
    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1101

	
1102
    int compNum = 0;
1103
    Visitor visitor(graph, compMap, compNum);
1104

	
1105
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1106
    dfs.init();
1107

	
1108
    for (NodeIt it(graph); it != INVALID; ++it) {
1109
      if (!dfs.reached(it)) {
1110
        dfs.addSource(it);
1111
        dfs.start();
1112
      }
1113
    }
1114
    return compNum;
1115
  }
1116

	
1117
  /// \ingroup connectivity
1118
  ///
1119
  /// \brief Find the bi-edge-connected cut edges.
1120
  ///
1121
  /// This function finds the bi-edge-connected components in an undirected
1122
  /// graph. The bi-edge-connected components are the classes of an equivalence
1123
  /// relation on the nodes. Two nodes are in relationship when they are
1124
  /// connected with at least two edge-disjoint paths. The bi-edge-connected
1125
  /// components are separted by edges which are the cut edges of the
1126
  /// components.
1127
  ///
1128
  /// \param graph The graph.
1129
  /// \retval cutMap A writable node map. The values will be set true when the
1130
  /// edge is a cut edge.
1131
  /// \return The number of cut edges.
1132
  template <typename Graph, typename EdgeMap>
1133
  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
1134
    checkConcept<concepts::Graph, Graph>();
1135
    typedef typename Graph::NodeIt NodeIt;
1136
    typedef typename Graph::Edge Edge;
1137
    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
1138

	
1139
    using namespace _topology_bits;
1140

	
1141
    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1142

	
1143
    int cutNum = 0;
1144
    Visitor visitor(graph, cutMap, cutNum);
1145

	
1146
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1147
    dfs.init();
1148

	
1149
    for (NodeIt it(graph); it != INVALID; ++it) {
1150
      if (!dfs.reached(it)) {
1151
        dfs.addSource(it);
1152
        dfs.start();
1153
      }
1154
    }
1155
    return cutNum;
1156
  }
1157

	
1158

	
1159
  namespace _topology_bits {
1160

	
1161
    template <typename Digraph, typename IntNodeMap>
1162
    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
1163
    public:
1164
      typedef typename Digraph::Node Node;
1165
      typedef typename Digraph::Arc edge;
1166

	
1167
      TopologicalSortVisitor(IntNodeMap& order, int num)
1168
        : _order(order), _num(num) {}
1169

	
1170
      void leave(const Node& node) {
1171
        _order.set(node, --_num);
1172
      }
1173

	
1174
    private:
1175
      IntNodeMap& _order;
1176
      int _num;
1177
    };
1178

	
1179
  }
1180

	
1181
  /// \ingroup connectivity
1182
  ///
1183
  /// \brief Sort the nodes of a DAG into topolgical order.
1184
  ///
1185
  /// Sort the nodes of a DAG into topolgical order.
1186
  ///
1187
  /// \param graph The graph. It must be directed and acyclic.
1188
  /// \retval order A writable node map. The values will be set from 0 to
1189
  /// the number of the nodes in the graph minus one. Each values of the map
1190
  /// will be set exactly once, the values  will be set descending order.
1191
  ///
1192
  /// \see checkedTopologicalSort
1193
  /// \see dag
1194
  template <typename Digraph, typename NodeMap>
1195
  void topologicalSort(const Digraph& graph, NodeMap& order) {
1196
    using namespace _topology_bits;
1197

	
1198
    checkConcept<concepts::Digraph, Digraph>();
1199
    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
1200

	
1201
    typedef typename Digraph::Node Node;
1202
    typedef typename Digraph::NodeIt NodeIt;
1203
    typedef typename Digraph::Arc Arc;
1204

	
1205
    TopologicalSortVisitor<Digraph, NodeMap>
1206
      visitor(order, countNodes(graph));
1207

	
1208
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1209
      dfs(graph, visitor);
1210

	
1211
    dfs.init();
1212
    for (NodeIt it(graph); it != INVALID; ++it) {
1213
      if (!dfs.reached(it)) {
1214
        dfs.addSource(it);
1215
        dfs.start();
1216
      }
1217
    }
1218
  }
1219

	
1220
  /// \ingroup connectivity
1221
  ///
1222
  /// \brief Sort the nodes of a DAG into topolgical order.
1223
  ///
1224
  /// Sort the nodes of a DAG into topolgical order. It also checks
1225
  /// that the given graph is DAG.
1226
  ///
1227
  /// \param graph The graph. It must be directed and acyclic.
1228
  /// \retval order A readable - writable node map. The values will be set
1229
  /// from 0 to the number of the nodes in the graph minus one. Each values
1230
  /// of the map will be set exactly once, the values will be set descending
1231
  /// order.
1232
  /// \return %False when the graph is not DAG.
1233
  ///
1234
  /// \see topologicalSort
1235
  /// \see dag
1236
  template <typename Digraph, typename NodeMap>
1237
  bool checkedTopologicalSort(const Digraph& graph, NodeMap& order) {
1238
    using namespace _topology_bits;
1239

	
1240
    checkConcept<concepts::Digraph, Digraph>();
1241
    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
1242
      NodeMap>();
1243

	
1244
    typedef typename Digraph::Node Node;
1245
    typedef typename Digraph::NodeIt NodeIt;
1246
    typedef typename Digraph::Arc Arc;
1247

	
1248
    order = constMap<Node, int, -1>();
1249

	
1250
    TopologicalSortVisitor<Digraph, NodeMap>
1251
      visitor(order, countNodes(graph));
1252

	
1253
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1254
      dfs(graph, visitor);
1255

	
1256
    dfs.init();
1257
    for (NodeIt it(graph); it != INVALID; ++it) {
1258
      if (!dfs.reached(it)) {
1259
        dfs.addSource(it);
1260
        while (!dfs.emptyQueue()) {
1261
           Arc edge = dfs.nextArc();
1262
           Node target = graph.target(edge);
1263
           if (dfs.reached(target) && order[target] == -1) {
1264
             return false;
1265
           }
1266
           dfs.processNextArc();
1267
         }
1268
      }
1269
    }
1270
    return true;
1271
  }
1272

	
1273
  /// \ingroup connectivity
1274
  ///
1275
  /// \brief Check that the given directed graph is a DAG.
1276
  ///
1277
  /// Check that the given directed graph is a DAG. The DAG is
1278
  /// an Directed Acyclic Digraph.
1279
  /// \return %False when the graph is not DAG.
1280
  /// \see acyclic
1281
  template <typename Digraph>
1282
  bool dag(const Digraph& graph) {
1283

	
1284
    checkConcept<concepts::Digraph, Digraph>();
1285

	
1286
    typedef typename Digraph::Node Node;
1287
    typedef typename Digraph::NodeIt NodeIt;
1288
    typedef typename Digraph::Arc Arc;
1289

	
1290
    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1291

	
1292
    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1293
      Create dfs(graph);
1294

	
1295
    ProcessedMap processed(graph);
1296
    dfs.processedMap(processed);
1297

	
1298
    dfs.init();
1299
    for (NodeIt it(graph); it != INVALID; ++it) {
1300
      if (!dfs.reached(it)) {
1301
        dfs.addSource(it);
1302
        while (!dfs.emptyQueue()) {
1303
          Arc edge = dfs.nextArc();
1304
          Node target = graph.target(edge);
1305
          if (dfs.reached(target) && !processed[target]) {
1306
            return false;
1307
          }
1308
          dfs.processNextArc();
1309
        }
1310
      }
1311
    }
1312
    return true;
1313
  }
1314

	
1315
  /// \ingroup connectivity
1316
  ///
1317
  /// \brief Check that the given undirected graph is acyclic.
1318
  ///
1319
  /// Check that the given undirected graph acyclic.
1320
  /// \param graph The undirected graph.
1321
  /// \return %True when there is no circle in the graph.
1322
  /// \see dag
1323
  template <typename Graph>
1324
  bool acyclic(const Graph& graph) {
1325
    checkConcept<concepts::Graph, Graph>();
1326
    typedef typename Graph::Node Node;
1327
    typedef typename Graph::NodeIt NodeIt;
1328
    typedef typename Graph::Arc Arc;
1329
    Dfs<Graph> dfs(graph);
1330
    dfs.init();
1331
    for (NodeIt it(graph); it != INVALID; ++it) {
1332
      if (!dfs.reached(it)) {
1333
        dfs.addSource(it);
1334
        while (!dfs.emptyQueue()) {
1335
          Arc edge = dfs.nextArc();
1336
          Node source = graph.source(edge);
1337
          Node target = graph.target(edge);
1338
          if (dfs.reached(target) &&
1339
              dfs.predArc(source) != graph.oppositeArc(edge)) {
1340
            return false;
1341
          }
1342
          dfs.processNextArc();
1343
        }
1344
      }
1345
    }
1346
    return true;
1347
  }
1348

	
1349
  /// \ingroup connectivity
1350
  ///
1351
  /// \brief Check that the given undirected graph is tree.
1352
  ///
1353
  /// Check that the given undirected graph is tree.
1354
  /// \param graph The undirected graph.
1355
  /// \return %True when the graph is acyclic and connected.
1356
  template <typename Graph>
1357
  bool tree(const Graph& graph) {
1358
    checkConcept<concepts::Graph, Graph>();
1359
    typedef typename Graph::Node Node;
1360
    typedef typename Graph::NodeIt NodeIt;
1361
    typedef typename Graph::Arc Arc;
1362
    Dfs<Graph> dfs(graph);
1363
    dfs.init();
1364
    dfs.addSource(NodeIt(graph));
1365
    while (!dfs.emptyQueue()) {
1366
      Arc edge = dfs.nextArc();
1367
      Node source = graph.source(edge);
1368
      Node target = graph.target(edge);
1369
      if (dfs.reached(target) &&
1370
          dfs.predArc(source) != graph.oppositeArc(edge)) {
1371
        return false;
1372
      }
1373
      dfs.processNextArc();
1374
    }
1375
    for (NodeIt it(graph); it != INVALID; ++it) {
1376
      if (!dfs.reached(it)) {
1377
        return false;
1378
      }
1379
    }
1380
    return true;
1381
  }
1382

	
1383
  namespace _topology_bits {
1384

	
1385
    template <typename Digraph>
1386
    class BipartiteVisitor : public BfsVisitor<Digraph> {
1387
    public:
1388
      typedef typename Digraph::Arc Arc;
1389
      typedef typename Digraph::Node Node;
1390

	
1391
      BipartiteVisitor(const Digraph& graph, bool& bipartite)
1392
        : _graph(graph), _part(graph), _bipartite(bipartite) {}
1393

	
1394
      void start(const Node& node) {
1395
        _part[node] = true;
1396
      }
1397
      void discover(const Arc& edge) {
1398
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1399
      }
1400
      void examine(const Arc& edge) {
1401
        _bipartite = _bipartite &&
1402
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1403
      }
1404

	
1405
    private:
1406

	
1407
      const Digraph& _graph;
1408
      typename Digraph::template NodeMap<bool> _part;
1409
      bool& _bipartite;
1410
    };
1411

	
1412
    template <typename Digraph, typename PartMap>
1413
    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
1414
    public:
1415
      typedef typename Digraph::Arc Arc;
1416
      typedef typename Digraph::Node Node;
1417

	
1418
      BipartitePartitionsVisitor(const Digraph& graph,
1419
                                 PartMap& part, bool& bipartite)
1420
        : _graph(graph), _part(part), _bipartite(bipartite) {}
1421

	
1422
      void start(const Node& node) {
1423
        _part.set(node, true);
1424
      }
1425
      void discover(const Arc& edge) {
1426
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1427
      }
1428
      void examine(const Arc& edge) {
1429
        _bipartite = _bipartite &&
1430
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1431
      }
1432

	
1433
    private:
1434

	
1435
      const Digraph& _graph;
1436
      PartMap& _part;
1437
      bool& _bipartite;
1438
    };
1439
  }
1440

	
1441
  /// \ingroup connectivity
1442
  ///
1443
  /// \brief Check if the given undirected graph is bipartite or not
1444
  ///
1445
  /// The function checks if the given undirected \c graph graph is bipartite
1446
  /// or not. The \ref Bfs algorithm is used to calculate the result.
1447
  /// \param graph The undirected graph.
1448
  /// \return %True if \c graph is bipartite, %false otherwise.
1449
  /// \sa bipartitePartitions
1450
  template<typename Graph>
1451
  inline bool bipartite(const Graph &graph){
1452
    using namespace _topology_bits;
1453

	
1454
    checkConcept<concepts::Graph, Graph>();
1455

	
1456
    typedef typename Graph::NodeIt NodeIt;
1457
    typedef typename Graph::ArcIt ArcIt;
1458

	
1459
    bool bipartite = true;
1460

	
1461
    BipartiteVisitor<Graph>
1462
      visitor(graph, bipartite);
1463
    BfsVisit<Graph, BipartiteVisitor<Graph> >
1464
      bfs(graph, visitor);
1465
    bfs.init();
1466
    for(NodeIt it(graph); it != INVALID; ++it) {
1467
      if(!bfs.reached(it)){
1468
        bfs.addSource(it);
1469
        while (!bfs.emptyQueue()) {
1470
          bfs.processNextNode();
1471
          if (!bipartite) return false;
1472
        }
1473
      }
1474
    }
1475
    return true;
1476
  }
1477

	
1478
  /// \ingroup connectivity
1479
  ///
1480
  /// \brief Check if the given undirected graph is bipartite or not
1481
  ///
1482
  /// The function checks if the given undirected graph is bipartite
1483
  /// or not. The  \ref  Bfs  algorithm  is   used  to  calculate the result.
1484
  /// During the execution, the \c partMap will be set as the two
1485
  /// partitions of the graph.
1486
  /// \param graph The undirected graph.
1487
  /// \retval partMap A writable bool map of nodes. It will be set as the
1488
  /// two partitions of the graph.
1489
  /// \return %True if \c graph is bipartite, %false otherwise.
1490
  template<typename Graph, typename NodeMap>
1491
  inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
1492
    using namespace _topology_bits;
1493

	
1494
    checkConcept<concepts::Graph, Graph>();
1495

	
1496
    typedef typename Graph::Node Node;
1497
    typedef typename Graph::NodeIt NodeIt;
1498
    typedef typename Graph::ArcIt ArcIt;
1499

	
1500
    bool bipartite = true;
1501

	
1502
    BipartitePartitionsVisitor<Graph, NodeMap>
1503
      visitor(graph, partMap, bipartite);
1504
    BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
1505
      bfs(graph, visitor);
1506
    bfs.init();
1507
    for(NodeIt it(graph); it != INVALID; ++it) {
1508
      if(!bfs.reached(it)){
1509
        bfs.addSource(it);
1510
        while (!bfs.emptyQueue()) {
1511
          bfs.processNextNode();
1512
          if (!bipartite) return false;
1513
        }
1514
      }
1515
    }
1516
    return true;
1517
  }
1518

	
1519
  /// \brief Returns true when there are not loop edges in the graph.
1520
  ///
1521
  /// Returns true when there are not loop edges in the graph.
1522
  template <typename Digraph>
1523
  bool loopFree(const Digraph& graph) {
1524
    for (typename Digraph::ArcIt it(graph); it != INVALID; ++it) {
1525
      if (graph.source(it) == graph.target(it)) return false;
1526
    }
1527
    return true;
1528
  }
1529

	
1530
  /// \brief Returns true when there are not parallel edges in the graph.
1531
  ///
1532
  /// Returns true when there are not parallel edges in the graph.
1533
  template <typename Digraph>
1534
  bool parallelFree(const Digraph& graph) {
1535
    typename Digraph::template NodeMap<bool> reached(graph, false);
1536
    for (typename Digraph::NodeIt n(graph); n != INVALID; ++n) {
1537
      for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
1538
        if (reached[graph.target(e)]) return false;
1539
        reached.set(graph.target(e), true);
1540
      }
1541
      for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
1542
        reached.set(graph.target(e), false);
1543
      }
1544
    }
1545
    return true;
1546
  }
1547

	
1548
  /// \brief Returns true when there are not loop edges and parallel
1549
  /// edges in the graph.
1550
  ///
1551
  /// Returns true when there are not loop edges and parallel edges in
1552
  /// the graph.
1553
  template <typename Digraph>
1554
  bool simpleDigraph(const Digraph& graph) {
1555
    typename Digraph::template NodeMap<bool> reached(graph, false);
1556
    for (typename Digraph::NodeIt n(graph); n != INVALID; ++n) {
1557
      reached.set(n, true);
1558
      for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
1559
        if (reached[graph.target(e)]) return false;
1560
        reached.set(graph.target(e), true);
1561
      }
1562
      for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
1563
        reached.set(graph.target(e), false);
1564
      }
1565
      reached.set(n, false);
1566
    }
1567
    return true;
1568
  }
1569

	
1570
} //namespace lemon
1571

	
1572
#endif //LEMON_TOPOLOGY_H
0 comments (0 inline)