gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Renamings in connectivity.h and bug fix in DfsVisit (#61) - The include guard, the private namespace and some local varibles are renamed - The stop() must be called in DfsVisit, if there are not outgoing arcs from the added node
0 2 0
default
2 files changed with 65 insertions and 61 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19
#ifndef LEMON_TOPOLOGY_H
20
#define LEMON_TOPOLOGY_H
19
#ifndef LEMON_CONNECTIVITY_H
20
#define LEMON_CONNECTIVITY_H
21 21

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

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

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

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

	
41 41
namespace lemon {
42 42

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

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

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

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

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

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

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

	
157
  namespace _topology_bits {
157
  namespace _connectivity_bits {
158 158

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

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

	
169 169
    private:
170 170
      Iterator _it;
171 171
    };
172 172

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

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

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

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

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

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

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

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

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

	
227 227
  }
228 228

	
229 229

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

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

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

	
251
    using namespace _topology_bits;
251
    using namespace _connectivity_bits;
252 252

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

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

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

	
267 267
    typedef ReverseDigraph<const Digraph> RDigraph;
268
    typedef typename RDigraph::NodeIt RNodeIt;
268 269
    RDigraph rdigraph(digraph);
269 270

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

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

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

	
284 285
    return true;
285 286
  }
286 287

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

	
305
    using namespace _topology_bits;
306
    using namespace _connectivity_bits;
306 307

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

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

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

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

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

	
331 332
    RDigraph rdigraph(digraph);
332 333

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

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

	
338 339
    int compNum = 0;
339 340

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

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

	
377
    using namespace _topology_bits;
378
    using namespace _connectivity_bits;
378 379

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

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

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

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

	
398 399
    RDigraph rdigraph(digraph);
399 400

	
400 401
    int compNum = 0;
401 402

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

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

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

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

	
441
    using namespace _topology_bits;
442
    using namespace _connectivity_bits;
442 443

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

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

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

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

	
462 463
    RDigraph rgraph(graph);
463 464

	
464 465
    int cutNum = 0;
465 466

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

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

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

	
481
  namespace _topology_bits {
482
  namespace _connectivity_bits {
482 483

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

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

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

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

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

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

	
522 523
      void backtrack(const Arc& edge) {
523 524
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
524 525
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
525 526
        }
526 527
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
527 528
          ++_compNum;
528 529
        }
529 530
      }
... ...
@@ -685,199 +686,199 @@
685 686
      const Digraph& _graph;
686 687
      NodeMap& _cutMap;
687 688
      int& _cutNum;
688 689

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

	
697 698
  }
698 699

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

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

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

	
733
    using namespace _topology_bits;
734
    using namespace _connectivity_bits;
734 735

	
735 736
    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
736 737

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

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

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

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

	
776
    using namespace _topology_bits;
777
    using namespace _connectivity_bits;
777 778

	
778 779
    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
779 780

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

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

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

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

	
816
    using namespace _topology_bits;
817
    using namespace _connectivity_bits;
817 818

	
818 819
    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
819 820

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

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

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

	
835
  namespace _topology_bits {
836
  namespace _connectivity_bits {
836 837

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

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

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

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

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

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

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

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

	
883 884
    private:
... ...
@@ -1008,565 +1009,567 @@
1008 1009
      }
1009 1010

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

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

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

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

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

	
1056
    using namespace _topology_bits;
1057
    using namespace _connectivity_bits;
1057 1058

	
1058 1059
    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1059 1060

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

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

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

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

	
1098
    using namespace _topology_bits;
1099
    using namespace _connectivity_bits;
1099 1100

	
1100 1101
    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1101 1102

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

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

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

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

	
1139
    using namespace _topology_bits;
1140
    using namespace _connectivity_bits;
1140 1141

	
1141 1142
    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1142 1143

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

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

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

	
1158 1159

	
1159
  namespace _topology_bits {
1160
  namespace _connectivity_bits {
1160 1161

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

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

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

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

	
1179 1180
  }
1180 1181

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

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

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

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

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

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

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

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

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

	
1248
    order = constMap<Node, int, -1>();
1249
    for (NodeIt it(digraph); it != INVALID; ++it) {
1250
      order.set(it, -1);
1251
    }
1249 1252

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

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

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

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

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

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

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

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

	
1295
    ProcessedMap processed(graph);
1298
    ProcessedMap processed(digraph);
1296 1299
    dfs.processedMap(processed);
1297 1300

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

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

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

	
1383
  namespace _topology_bits {
1386
  namespace _connectivity_bits {
1384 1387

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

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

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

	
1405 1408
    private:
1406 1409

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

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

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

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

	
1433 1436
    private:
1434 1437

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

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

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

	
1456 1459
    typedef typename Graph::NodeIt NodeIt;
1457 1460
    typedef typename Graph::ArcIt ArcIt;
1458 1461

	
1459 1462
    bool bipartite = true;
1460 1463

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

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

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

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

	
1500 1503
    bool bipartite = true;
1501 1504

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

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

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

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

	
1570 1573
} //namespace lemon
1571 1574

	
1572
#endif //LEMON_TOPOLOGY_H
1575
#endif //LEMON_CONNECTIVITY_H
Ignore white space 96 line context
... ...
@@ -1365,96 +1365,97 @@
1365 1365
    }
1366 1366

	
1367 1367
  public:
1368 1368

	
1369 1369
    /// \name Execution Control
1370 1370
    /// The simplest way to execute the DFS algorithm is to use one of the
1371 1371
    /// member functions called \ref run(Node) "run()".\n
1372 1372
    /// If you need more control on the execution, first you have to call
1373 1373
    /// \ref init(), then you can add a source node with \ref addSource()
1374 1374
    /// and perform the actual computation with \ref start().
1375 1375
    /// This procedure can be repeated if there are nodes that have not
1376 1376
    /// been reached.
1377 1377

	
1378 1378
    /// @{
1379 1379

	
1380 1380
    /// \brief Initializes the internal data structures.
1381 1381
    ///
1382 1382
    /// Initializes the internal data structures.
1383 1383
    void init() {
1384 1384
      create_maps();
1385 1385
      _stack.resize(countNodes(*_digraph));
1386 1386
      _stack_head = -1;
1387 1387
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1388 1388
        _reached->set(u, false);
1389 1389
      }
1390 1390
    }
1391 1391

	
1392 1392
    /// \brief Adds a new source node.
1393 1393
    ///
1394 1394
    /// Adds a new source node to the set of nodes to be processed.
1395 1395
    ///
1396 1396
    /// \pre The stack must be empty. Otherwise the algorithm gives
1397 1397
    /// wrong results. (One of the outgoing arcs of all the source nodes
1398 1398
    /// except for the last one will not be visited and distances will
1399 1399
    /// also be wrong.)
1400 1400
    void addSource(Node s)
1401 1401
    {
1402 1402
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
1403 1403
      if(!(*_reached)[s]) {
1404 1404
          _reached->set(s,true);
1405 1405
          _visitor->start(s);
1406 1406
          _visitor->reach(s);
1407 1407
          Arc e;
1408 1408
          _digraph->firstOut(e, s);
1409 1409
          if (e != INVALID) {
1410 1410
            _stack[++_stack_head] = e;
1411 1411
          } else {
1412 1412
            _visitor->leave(s);
1413
            _visitor->stop(s);
1413 1414
          }
1414 1415
        }
1415 1416
    }
1416 1417

	
1417 1418
    /// \brief Processes the next arc.
1418 1419
    ///
1419 1420
    /// Processes the next arc.
1420 1421
    ///
1421 1422
    /// \return The processed arc.
1422 1423
    ///
1423 1424
    /// \pre The stack must not be empty.
1424 1425
    Arc processNextArc() {
1425 1426
      Arc e = _stack[_stack_head];
1426 1427
      Node m = _digraph->target(e);
1427 1428
      if(!(*_reached)[m]) {
1428 1429
        _visitor->discover(e);
1429 1430
        _visitor->reach(m);
1430 1431
        _reached->set(m, true);
1431 1432
        _digraph->firstOut(_stack[++_stack_head], m);
1432 1433
      } else {
1433 1434
        _visitor->examine(e);
1434 1435
        m = _digraph->source(e);
1435 1436
        _digraph->nextOut(_stack[_stack_head]);
1436 1437
      }
1437 1438
      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
1438 1439
        _visitor->leave(m);
1439 1440
        --_stack_head;
1440 1441
        if (_stack_head >= 0) {
1441 1442
          _visitor->backtrack(_stack[_stack_head]);
1442 1443
          m = _digraph->source(_stack[_stack_head]);
1443 1444
          _digraph->nextOut(_stack[_stack_head]);
1444 1445
        } else {
1445 1446
          _visitor->stop(m);
1446 1447
        }
1447 1448
      }
1448 1449
      return e;
1449 1450
    }
1450 1451

	
1451 1452
    /// \brief Next arc to be processed.
1452 1453
    ///
1453 1454
    /// Next arc to be processed.
1454 1455
    ///
1455 1456
    /// \return The next arc to be processed or INVALID if the stack is
1456 1457
    /// empty.
1457 1458
    Arc nextArc() const {
1458 1459
      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
1459 1460
    }
1460 1461

	
0 comments (0 inline)