gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Doc improvements and fixes for connectivity tools (#285) And add loopFree(), parallelFree(), simpleGraph() to the module doc.
0 2 0
default
2 files changed with 305 insertions and 225 deletions:
↑ Collapse diff ↑
Show white space 34359738368 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-2009
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 19
#ifndef LEMON_CONNECTIVITY_H
20 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 graph_properties
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 graph_properties
44 44
  ///
45
  /// \brief Check whether the given undirected graph is connected.
45
  /// \brief Check whether an undirected graph is connected.
46 46
  ///
47
  /// Check whether the given undirected graph is connected.
48
  /// \param graph The undirected graph.
49
  /// \return \c true when there is path between any two nodes in the graph.
47
  /// This function checks whether the given undirected graph is connected,
48
  /// i.e. there is a path between any two nodes in the graph.
49
  ///
50
  /// \return \c true if the graph is connected.
50 51
  /// \note By definition, the empty graph is connected.
52
  ///
53
  /// \see countConnectedComponents(), connectedComponents()
54
  /// \see stronglyConnected()
51 55
  template <typename Graph>
52 56
  bool connected(const Graph& graph) {
53 57
    checkConcept<concepts::Graph, Graph>();
54 58
    typedef typename Graph::NodeIt NodeIt;
55 59
    if (NodeIt(graph) == INVALID) return true;
56 60
    Dfs<Graph> dfs(graph);
57 61
    dfs.run(NodeIt(graph));
58 62
    for (NodeIt it(graph); it != INVALID; ++it) {
59 63
      if (!dfs.reached(it)) {
60 64
        return false;
61 65
      }
62 66
    }
63 67
    return true;
64 68
  }
65 69

	
66 70
  /// \ingroup graph_properties
67 71
  ///
68 72
  /// \brief Count the number of connected components of an undirected graph
69 73
  ///
70
  /// Count the number of connected components of an undirected graph
74
  /// This function counts the number of connected components of the given
75
  /// undirected graph.
71 76
  ///
72
  /// \param graph The graph. It must be undirected.
73
  /// \return The number of components
77
  /// The connected components are the classes of an equivalence relation
78
  /// on the nodes of an undirected graph. Two nodes are in the same class
79
  /// if they are connected with a path.
80
  ///
81
  /// \return The number of connected components.
74 82
  /// \note By definition, the empty graph consists
75 83
  /// of zero connected components.
84
  ///
85
  /// \see connected(), connectedComponents()
76 86
  template <typename Graph>
77 87
  int countConnectedComponents(const Graph &graph) {
78 88
    checkConcept<concepts::Graph, Graph>();
79 89
    typedef typename Graph::Node Node;
80 90
    typedef typename Graph::Arc Arc;
81 91

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

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

	
91 101
    PredMap predMap;
92 102
    bfs.predMap(predMap);
93 103

	
94 104
    DistMap distMap;
95 105
    bfs.distMap(distMap);
96 106

	
97 107
    bfs.init();
98 108
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
99 109
      if (!bfs.reached(n)) {
100 110
        bfs.addSource(n);
101 111
        bfs.start();
102 112
        ++compNum;
103 113
      }
104 114
    }
105 115
    return compNum;
106 116
  }
107 117

	
108 118
  /// \ingroup graph_properties
109 119
  ///
110 120
  /// \brief Find the connected components of an undirected graph
111 121
  ///
112
  /// Find the connected components of an undirected graph.
122
  /// This function finds the connected components of the given undirected
123
  /// graph.
124
  ///
125
  /// The connected components are the classes of an equivalence relation
126
  /// on the nodes of an undirected graph. Two nodes are in the same class
127
  /// if they are connected with a path.
113 128
  ///
114 129
  /// \image html connected_components.png
115 130
  /// \image latex connected_components.eps "Connected components" width=\textwidth
116 131
  ///
117
  /// \param graph The graph. It must be undirected.
132
  /// \param graph The undirected graph.
118 133
  /// \retval compMap A writable node map. The values will be set from 0 to
119
  /// the number of the connected components minus one. Each values of the map
120
  /// will be set exactly once, the values of a certain component will be
134
  /// the number of the connected components minus one. Each value of the map
135
  /// will be set exactly once, and the values of a certain component will be
121 136
  /// set continuously.
122
  /// \return The number of components
137
  /// \return The number of connected components.
138
  /// \note By definition, the empty graph consists
139
  /// of zero connected components.
140
  ///
141
  /// \see connected(), countConnectedComponents()
123 142
  template <class Graph, class NodeMap>
124 143
  int connectedComponents(const Graph &graph, NodeMap &compMap) {
125 144
    checkConcept<concepts::Graph, Graph>();
126 145
    typedef typename Graph::Node Node;
127 146
    typedef typename Graph::Arc Arc;
128 147
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
129 148

	
130 149
    typedef NullMap<Node, Arc> PredMap;
131 150
    typedef NullMap<Node, int> DistMap;
132 151

	
133 152
    int compNum = 0;
134 153
    typename Bfs<Graph>::
135 154
      template SetPredMap<PredMap>::
136 155
      template SetDistMap<DistMap>::
137 156
      Create bfs(graph);
138 157

	
139 158
    PredMap predMap;
140 159
    bfs.predMap(predMap);
141 160

	
142 161
    DistMap distMap;
143 162
    bfs.distMap(distMap);
144 163

	
145 164
    bfs.init();
146 165
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
147 166
      if(!bfs.reached(n)) {
148 167
        bfs.addSource(n);
149 168
        while (!bfs.emptyQueue()) {
150 169
          compMap.set(bfs.nextNode(), compNum);
151 170
          bfs.processNextNode();
152 171
        }
153 172
        ++compNum;
154 173
      }
155 174
    }
156 175
    return compNum;
157 176
  }
158 177

	
159 178
  namespace _connectivity_bits {
160 179

	
161 180
    template <typename Digraph, typename Iterator >
162 181
    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
163 182
    public:
164 183
      typedef typename Digraph::Node Node;
165 184
      LeaveOrderVisitor(Iterator it) : _it(it) {}
166 185

	
167 186
      void leave(const Node& node) {
168 187
        *(_it++) = node;
169 188
      }
170 189

	
171 190
    private:
172 191
      Iterator _it;
173 192
    };
174 193

	
175 194
    template <typename Digraph, typename Map>
176 195
    struct FillMapVisitor : public DfsVisitor<Digraph> {
177 196
    public:
178 197
      typedef typename Digraph::Node Node;
179 198
      typedef typename Map::Value Value;
180 199

	
181 200
      FillMapVisitor(Map& map, Value& value)
182 201
        : _map(map), _value(value) {}
183 202

	
184 203
      void reach(const Node& node) {
185 204
        _map.set(node, _value);
186 205
      }
187 206
    private:
188 207
      Map& _map;
189 208
      Value& _value;
190 209
    };
191 210

	
192 211
    template <typename Digraph, typename ArcMap>
193 212
    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
194 213
    public:
195 214
      typedef typename Digraph::Node Node;
196 215
      typedef typename Digraph::Arc Arc;
197 216

	
198 217
      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
199 218
                                      ArcMap& cutMap,
200 219
                                      int& cutNum)
201 220
        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
202 221
          _compMap(digraph, -1), _num(-1) {
203 222
      }
204 223

	
205 224
      void start(const Node&) {
206 225
        ++_num;
207 226
      }
208 227

	
209 228
      void reach(const Node& node) {
210 229
        _compMap.set(node, _num);
211 230
      }
212 231

	
213 232
      void examine(const Arc& arc) {
214 233
         if (_compMap[_digraph.source(arc)] !=
215 234
             _compMap[_digraph.target(arc)]) {
216 235
           _cutMap.set(arc, true);
217 236
           ++_cutNum;
218 237
         }
219 238
      }
220 239
    private:
221 240
      const Digraph& _digraph;
222 241
      ArcMap& _cutMap;
223 242
      int& _cutNum;
224 243

	
225 244
      typename Digraph::template NodeMap<int> _compMap;
226 245
      int _num;
227 246
    };
228 247

	
229 248
  }
230 249

	
231 250

	
232 251
  /// \ingroup graph_properties
233 252
  ///
234
  /// \brief Check whether the given directed graph is strongly connected.
253
  /// \brief Check whether a directed graph is strongly connected.
235 254
  ///
236
  /// Check whether the given directed graph is strongly connected. The
237
  /// graph is strongly connected when any two nodes of the graph are
255
  /// This function checks whether the given directed graph is strongly
256
  /// connected, i.e. any two nodes of the digraph are
238 257
  /// connected with directed paths in both direction.
239
  /// \return \c false when the graph is not strongly connected.
240
  /// \see connected
241 258
  ///
242
  /// \note By definition, the empty graph is strongly connected.
259
  /// \return \c true if the digraph is strongly connected.
260
  /// \note By definition, the empty digraph is strongly connected.
261
  /// 
262
  /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
263
  /// \see connected()
243 264
  template <typename Digraph>
244 265
  bool stronglyConnected(const Digraph& digraph) {
245 266
    checkConcept<concepts::Digraph, Digraph>();
246 267

	
247 268
    typedef typename Digraph::Node Node;
248 269
    typedef typename Digraph::NodeIt NodeIt;
249 270

	
250 271
    typename Digraph::Node source = NodeIt(digraph);
251 272
    if (source == INVALID) return true;
252 273

	
253 274
    using namespace _connectivity_bits;
254 275

	
255 276
    typedef DfsVisitor<Digraph> Visitor;
256 277
    Visitor visitor;
257 278

	
258 279
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
259 280
    dfs.init();
260 281
    dfs.addSource(source);
261 282
    dfs.start();
262 283

	
263 284
    for (NodeIt it(digraph); it != INVALID; ++it) {
264 285
      if (!dfs.reached(it)) {
265 286
        return false;
266 287
      }
267 288
    }
268 289

	
269 290
    typedef ReverseDigraph<const Digraph> RDigraph;
270 291
    typedef typename RDigraph::NodeIt RNodeIt;
271 292
    RDigraph rdigraph(digraph);
272 293

	
273
    typedef DfsVisitor<Digraph> RVisitor;
294
    typedef DfsVisitor<RDigraph> RVisitor;
274 295
    RVisitor rvisitor;
275 296

	
276 297
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
277 298
    rdfs.init();
278 299
    rdfs.addSource(source);
279 300
    rdfs.start();
280 301

	
281 302
    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
282 303
      if (!rdfs.reached(it)) {
283 304
        return false;
284 305
      }
285 306
    }
286 307

	
287 308
    return true;
288 309
  }
289 310

	
290 311
  /// \ingroup graph_properties
291 312
  ///
292
  /// \brief Count the strongly connected components of a directed graph
313
  /// \brief Count the number of strongly connected components of a 
314
  /// directed graph
293 315
  ///
294
  /// Count the strongly connected components of a directed graph.
316
  /// This function counts the number of strongly connected components of
317
  /// the given directed graph.
318
  ///
295 319
  /// The strongly connected components are the classes of an
296
  /// equivalence relation on the nodes of the graph. Two nodes are in
320
  /// equivalence relation on the nodes of a digraph. Two nodes are in
297 321
  /// the same class if they are connected with directed paths in both
298 322
  /// direction.
299 323
  ///
300
  /// \param digraph The graph.
301
  /// \return The number of components
302
  /// \note By definition, the empty graph has zero
324
  /// \return The number of strongly connected components.
325
  /// \note By definition, the empty digraph has zero
303 326
  /// strongly connected components.
327
  ///
328
  /// \see stronglyConnected(), stronglyConnectedComponents()
304 329
  template <typename Digraph>
305 330
  int countStronglyConnectedComponents(const Digraph& digraph) {
306 331
    checkConcept<concepts::Digraph, Digraph>();
307 332

	
308 333
    using namespace _connectivity_bits;
309 334

	
310 335
    typedef typename Digraph::Node Node;
311 336
    typedef typename Digraph::Arc Arc;
312 337
    typedef typename Digraph::NodeIt NodeIt;
313 338
    typedef typename Digraph::ArcIt ArcIt;
314 339

	
315 340
    typedef std::vector<Node> Container;
316 341
    typedef typename Container::iterator Iterator;
317 342

	
318 343
    Container nodes(countNodes(digraph));
319 344
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
320 345
    Visitor visitor(nodes.begin());
321 346

	
322 347
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
323 348
    dfs.init();
324 349
    for (NodeIt it(digraph); it != INVALID; ++it) {
325 350
      if (!dfs.reached(it)) {
326 351
        dfs.addSource(it);
327 352
        dfs.start();
328 353
      }
329 354
    }
330 355

	
331 356
    typedef typename Container::reverse_iterator RIterator;
332 357
    typedef ReverseDigraph<const Digraph> RDigraph;
333 358

	
334 359
    RDigraph rdigraph(digraph);
335 360

	
336 361
    typedef DfsVisitor<Digraph> RVisitor;
337 362
    RVisitor rvisitor;
338 363

	
339 364
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
340 365

	
341 366
    int compNum = 0;
342 367

	
343 368
    rdfs.init();
344 369
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
345 370
      if (!rdfs.reached(*it)) {
346 371
        rdfs.addSource(*it);
347 372
        rdfs.start();
348 373
        ++compNum;
349 374
      }
350 375
    }
351 376
    return compNum;
352 377
  }
353 378

	
354 379
  /// \ingroup graph_properties
355 380
  ///
356 381
  /// \brief Find the strongly connected components of a directed graph
357 382
  ///
358
  /// Find the strongly connected components of a directed graph.  The
359
  /// strongly connected components are the classes of an equivalence
360
  /// relation on the nodes of the graph. Two nodes are in
361
  /// relationship when there are directed paths between them in both
362
  /// direction. In addition, the numbering of components will satisfy
363
  /// that there is no arc going from a higher numbered component to
364
  /// a lower.
383
  /// This function finds the strongly connected components of the given
384
  /// directed graph. In addition, the numbering of the components will
385
  /// satisfy that there is no arc going from a higher numbered component
386
  /// to a lower one (i.e. it provides a topological order of the components).
387
  ///
388
  /// The strongly connected components are the classes of an
389
  /// equivalence relation on the nodes of a digraph. Two nodes are in
390
  /// the same class if they are connected with directed paths in both
391
  /// direction.
365 392
  ///
366 393
  /// \image html strongly_connected_components.png
367 394
  /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
368 395
  ///
369 396
  /// \param digraph The digraph.
370 397
  /// \retval compMap A writable node map. The values will be set from 0 to
371 398
  /// the number of the strongly connected components minus one. Each value
372
  /// of the map will be set exactly once, the values of a certain component
373
  /// will be set continuously.
374
  /// \return The number of components
399
  /// of the map will be set exactly once, and the values of a certain
400
  /// component will be set continuously.
401
  /// \return The number of strongly connected components.
402
  /// \note By definition, the empty digraph has zero
403
  /// strongly connected components.
404
  ///
405
  /// \see stronglyConnected(), countStronglyConnectedComponents()
375 406
  template <typename Digraph, typename NodeMap>
376 407
  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
377 408
    checkConcept<concepts::Digraph, Digraph>();
378 409
    typedef typename Digraph::Node Node;
379 410
    typedef typename Digraph::NodeIt NodeIt;
380 411
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
381 412

	
382 413
    using namespace _connectivity_bits;
383 414

	
384 415
    typedef std::vector<Node> Container;
385 416
    typedef typename Container::iterator Iterator;
386 417

	
387 418
    Container nodes(countNodes(digraph));
388 419
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
389 420
    Visitor visitor(nodes.begin());
390 421

	
391 422
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
392 423
    dfs.init();
393 424
    for (NodeIt it(digraph); it != INVALID; ++it) {
394 425
      if (!dfs.reached(it)) {
395 426
        dfs.addSource(it);
396 427
        dfs.start();
397 428
      }
398 429
    }
399 430

	
400 431
    typedef typename Container::reverse_iterator RIterator;
401 432
    typedef ReverseDigraph<const Digraph> RDigraph;
402 433

	
403 434
    RDigraph rdigraph(digraph);
404 435

	
405 436
    int compNum = 0;
406 437

	
407 438
    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
408 439
    RVisitor rvisitor(compMap, compNum);
409 440

	
410 441
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
411 442

	
412 443
    rdfs.init();
413 444
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
414 445
      if (!rdfs.reached(*it)) {
415 446
        rdfs.addSource(*it);
416 447
        rdfs.start();
417 448
        ++compNum;
418 449
      }
419 450
    }
420 451
    return compNum;
421 452
  }
422 453

	
423 454
  /// \ingroup graph_properties
424 455
  ///
425 456
  /// \brief Find the cut arcs of the strongly connected components.
426 457
  ///
427
  /// Find the cut arcs of the strongly connected components.
428
  /// The strongly connected components are the classes of an equivalence
429
  /// relation on the nodes of the graph. Two nodes are in relationship
430
  /// when there are directed paths between them in both direction.
458
  /// This function finds the cut arcs of the strongly connected components
459
  /// of the given digraph.
460
  ///
461
  /// The strongly connected components are the classes of an
462
  /// equivalence relation on the nodes of a digraph. Two nodes are in
463
  /// the same class if they are connected with directed paths in both
464
  /// direction.
431 465
  /// The strongly connected components are separated by the cut arcs.
432 466
  ///
433
  /// \param graph The graph.
434
  /// \retval cutMap A writable node map. The values will be set true when the
435
  /// arc is a cut arc.
467
  /// \param digraph The digraph.
468
  /// \retval cutMap A writable arc map. The values will be set to \c true
469
  /// for the cut arcs (exactly once for each cut arc), and will not be
470
  /// changed for other arcs.
471
  /// \return The number of cut arcs.
436 472
  ///
437
  /// \return The number of cut arcs
473
  /// \see stronglyConnected(), stronglyConnectedComponents()
438 474
  template <typename Digraph, typename ArcMap>
439
  int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
475
  int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
440 476
    checkConcept<concepts::Digraph, Digraph>();
441 477
    typedef typename Digraph::Node Node;
442 478
    typedef typename Digraph::Arc Arc;
443 479
    typedef typename Digraph::NodeIt NodeIt;
444 480
    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
445 481

	
446 482
    using namespace _connectivity_bits;
447 483

	
448 484
    typedef std::vector<Node> Container;
449 485
    typedef typename Container::iterator Iterator;
450 486

	
451
    Container nodes(countNodes(graph));
487
    Container nodes(countNodes(digraph));
452 488
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
453 489
    Visitor visitor(nodes.begin());
454 490

	
455
    DfsVisit<Digraph, Visitor> dfs(graph, visitor);
491
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
456 492
    dfs.init();
457
    for (NodeIt it(graph); it != INVALID; ++it) {
493
    for (NodeIt it(digraph); it != INVALID; ++it) {
458 494
      if (!dfs.reached(it)) {
459 495
        dfs.addSource(it);
460 496
        dfs.start();
461 497
      }
462 498
    }
463 499

	
464 500
    typedef typename Container::reverse_iterator RIterator;
465 501
    typedef ReverseDigraph<const Digraph> RDigraph;
466 502

	
467
    RDigraph rgraph(graph);
503
    RDigraph rdigraph(digraph);
468 504

	
469 505
    int cutNum = 0;
470 506

	
471 507
    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
472
    RVisitor rvisitor(rgraph, cutMap, cutNum);
508
    RVisitor rvisitor(rdigraph, cutMap, cutNum);
473 509

	
474
    DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
510
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
475 511

	
476 512
    rdfs.init();
477 513
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
478 514
      if (!rdfs.reached(*it)) {
479 515
        rdfs.addSource(*it);
480 516
        rdfs.start();
481 517
      }
482 518
    }
483 519
    return cutNum;
484 520
  }
485 521

	
486 522
  namespace _connectivity_bits {
487 523

	
488 524
    template <typename Digraph>
489 525
    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
490 526
    public:
491 527
      typedef typename Digraph::Node Node;
492 528
      typedef typename Digraph::Arc Arc;
493 529
      typedef typename Digraph::Edge Edge;
494 530

	
495 531
      CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
496 532
        : _graph(graph), _compNum(compNum),
497 533
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
498 534

	
499 535
      void start(const Node& node) {
500 536
        _predMap.set(node, INVALID);
501 537
      }
502 538

	
503 539
      void reach(const Node& node) {
504 540
        _numMap.set(node, _num);
505 541
        _retMap.set(node, _num);
506 542
        ++_num;
507 543
      }
508 544

	
509 545
      void discover(const Arc& edge) {
510 546
        _predMap.set(_graph.target(edge), _graph.source(edge));
511 547
      }
512 548

	
513 549
      void examine(const Arc& edge) {
514 550
        if (_graph.source(edge) == _graph.target(edge) &&
515 551
            _graph.direction(edge)) {
516 552
          ++_compNum;
517 553
          return;
518 554
        }
519 555
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
520 556
          return;
521 557
        }
522 558
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
523 559
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
524 560
        }
525 561
      }
526 562

	
527 563
      void backtrack(const Arc& edge) {
528 564
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
529 565
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
530 566
        }
531 567
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
532 568
          ++_compNum;
533 569
        }
534 570
      }
535 571

	
536 572
    private:
537 573
      const Digraph& _graph;
538 574
      int& _compNum;
539 575

	
540 576
      typename Digraph::template NodeMap<int> _numMap;
541 577
      typename Digraph::template NodeMap<int> _retMap;
542 578
      typename Digraph::template NodeMap<Node> _predMap;
543 579
      int _num;
544 580
    };
545 581

	
546 582
    template <typename Digraph, typename ArcMap>
547 583
    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
548 584
    public:
549 585
      typedef typename Digraph::Node Node;
550 586
      typedef typename Digraph::Arc Arc;
551 587
      typedef typename Digraph::Edge Edge;
552 588

	
553 589
      BiNodeConnectedComponentsVisitor(const Digraph& graph,
554 590
                                       ArcMap& compMap, int &compNum)
555 591
        : _graph(graph), _compMap(compMap), _compNum(compNum),
556 592
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
557 593

	
558 594
      void start(const Node& node) {
559 595
        _predMap.set(node, INVALID);
560 596
      }
561 597

	
562 598
      void reach(const Node& node) {
563 599
        _numMap.set(node, _num);
564 600
        _retMap.set(node, _num);
565 601
        ++_num;
566 602
      }
567 603

	
568 604
      void discover(const Arc& edge) {
569 605
        Node target = _graph.target(edge);
570 606
        _predMap.set(target, edge);
571 607
        _edgeStack.push(edge);
572 608
      }
573 609

	
574 610
      void examine(const Arc& edge) {
575 611
        Node source = _graph.source(edge);
576 612
        Node target = _graph.target(edge);
577 613
        if (source == target && _graph.direction(edge)) {
578 614
          _compMap.set(edge, _compNum);
579 615
          ++_compNum;
580 616
          return;
581 617
        }
582 618
        if (_numMap[target] < _numMap[source]) {
583 619
          if (_predMap[source] != _graph.oppositeArc(edge)) {
584 620
            _edgeStack.push(edge);
585 621
          }
586 622
        }
587 623
        if (_predMap[source] != INVALID &&
588 624
            target == _graph.source(_predMap[source])) {
589 625
          return;
590 626
        }
591 627
        if (_retMap[source] > _numMap[target]) {
592 628
          _retMap.set(source, _numMap[target]);
593 629
        }
594 630
      }
595 631

	
596 632
      void backtrack(const Arc& edge) {
597 633
        Node source = _graph.source(edge);
598 634
        Node target = _graph.target(edge);
599 635
        if (_retMap[source] > _retMap[target]) {
600 636
          _retMap.set(source, _retMap[target]);
601 637
        }
602 638
        if (_numMap[source] <= _retMap[target]) {
603 639
          while (_edgeStack.top() != edge) {
604 640
            _compMap.set(_edgeStack.top(), _compNum);
605 641
            _edgeStack.pop();
606 642
          }
607 643
          _compMap.set(edge, _compNum);
608 644
          _edgeStack.pop();
609 645
          ++_compNum;
610 646
        }
611 647
      }
612 648

	
613 649
    private:
614 650
      const Digraph& _graph;
615 651
      ArcMap& _compMap;
616 652
      int& _compNum;
617 653

	
618 654
      typename Digraph::template NodeMap<int> _numMap;
619 655
      typename Digraph::template NodeMap<int> _retMap;
620 656
      typename Digraph::template NodeMap<Arc> _predMap;
621 657
      std::stack<Edge> _edgeStack;
622 658
      int _num;
623 659
    };
624 660

	
625 661

	
626 662
    template <typename Digraph, typename NodeMap>
627 663
    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
628 664
    public:
629 665
      typedef typename Digraph::Node Node;
630 666
      typedef typename Digraph::Arc Arc;
631 667
      typedef typename Digraph::Edge Edge;
632 668

	
633 669
      BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
634 670
                                     int& cutNum)
635 671
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
636 672
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
637 673

	
638 674
      void start(const Node& node) {
639 675
        _predMap.set(node, INVALID);
640 676
        rootCut = false;
641 677
      }
642 678

	
643 679
      void reach(const Node& node) {
644 680
        _numMap.set(node, _num);
645 681
        _retMap.set(node, _num);
646 682
        ++_num;
647 683
      }
648 684

	
649 685
      void discover(const Arc& edge) {
650 686
        _predMap.set(_graph.target(edge), _graph.source(edge));
651 687
      }
652 688

	
653 689
      void examine(const Arc& edge) {
654 690
        if (_graph.source(edge) == _graph.target(edge) &&
655 691
            _graph.direction(edge)) {
656 692
          if (!_cutMap[_graph.source(edge)]) {
657 693
            _cutMap.set(_graph.source(edge), true);
658 694
            ++_cutNum;
659 695
          }
660 696
          return;
661 697
        }
662 698
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
663 699
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
664 700
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
665 701
        }
666 702
      }
667 703

	
668 704
      void backtrack(const Arc& edge) {
669 705
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
670 706
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
671 707
        }
672 708
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
673 709
          if (_predMap[_graph.source(edge)] != INVALID) {
674 710
            if (!_cutMap[_graph.source(edge)]) {
675 711
              _cutMap.set(_graph.source(edge), true);
676 712
              ++_cutNum;
677 713
            }
678 714
          } else if (rootCut) {
679 715
            if (!_cutMap[_graph.source(edge)]) {
680 716
              _cutMap.set(_graph.source(edge), true);
681 717
              ++_cutNum;
682 718
            }
683 719
          } else {
684 720
            rootCut = true;
685 721
          }
686 722
        }
687 723
      }
688 724

	
689 725
    private:
690 726
      const Digraph& _graph;
691 727
      NodeMap& _cutMap;
692 728
      int& _cutNum;
693 729

	
694 730
      typename Digraph::template NodeMap<int> _numMap;
695 731
      typename Digraph::template NodeMap<int> _retMap;
696 732
      typename Digraph::template NodeMap<Node> _predMap;
697 733
      std::stack<Edge> _edgeStack;
698 734
      int _num;
699 735
      bool rootCut;
700 736
    };
701 737

	
702 738
  }
703 739

	
704 740
  template <typename Graph>
705 741
  int countBiNodeConnectedComponents(const Graph& graph);
706 742

	
707 743
  /// \ingroup graph_properties
708 744
  ///
709
  /// \brief Checks the graph is bi-node-connected.
745
  /// \brief Check whether an undirected graph is bi-node-connected.
710 746
  ///
711
  /// This function checks that the undirected graph is bi-node-connected
712
  /// graph. The graph is bi-node-connected if any two undirected edge is
713
  /// on same circle.
747
  /// This function checks whether the given undirected graph is 
748
  /// bi-node-connected, i.e. any two edges are on same circle.
714 749
  ///
715
  /// \param graph The graph.
716
  /// \return \c true when the graph bi-node-connected.
750
  /// \return \c true if the graph bi-node-connected.
751
  /// \note By definition, the empty graph is bi-node-connected.
752
  ///
753
  /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
717 754
  template <typename Graph>
718 755
  bool biNodeConnected(const Graph& graph) {
719 756
    return countBiNodeConnectedComponents(graph) <= 1;
720 757
  }
721 758

	
722 759
  /// \ingroup graph_properties
723 760
  ///
724
  /// \brief Count the biconnected components.
761
  /// \brief Count the number of bi-node-connected components of an 
762
  /// undirected graph.
725 763
  ///
726
  /// This function finds the bi-node-connected components in an undirected
727
  /// graph. The biconnected components are the classes of an equivalence
728
  /// relation on the undirected edges. Two undirected edge is in relationship
729
  /// when they are on same circle.
764
  /// This function counts the number of bi-node-connected components of
765
  /// the given undirected graph.
730 766
  ///
731
  /// \param graph The graph.
732
  /// \return The number of components.
767
  /// The bi-node-connected components are the classes of an equivalence
768
  /// relation on the edges of a undirected graph. Two edges are in the
769
  /// same class if they are on same circle.
770
  ///
771
  /// \return The number of bi-node-connected components.
772
  ///
773
  /// \see biNodeConnected(), biNodeConnectedComponents()
733 774
  template <typename Graph>
734 775
  int countBiNodeConnectedComponents(const Graph& graph) {
735 776
    checkConcept<concepts::Graph, Graph>();
736 777
    typedef typename Graph::NodeIt NodeIt;
737 778

	
738 779
    using namespace _connectivity_bits;
739 780

	
740 781
    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
741 782

	
742 783
    int compNum = 0;
743 784
    Visitor visitor(graph, compNum);
744 785

	
745 786
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
746 787
    dfs.init();
747 788

	
748 789
    for (NodeIt it(graph); it != INVALID; ++it) {
749 790
      if (!dfs.reached(it)) {
750 791
        dfs.addSource(it);
751 792
        dfs.start();
752 793
      }
753 794
    }
754 795
    return compNum;
755 796
  }
756 797

	
757 798
  /// \ingroup graph_properties
758 799
  ///
759
  /// \brief Find the bi-node-connected components.
800
  /// \brief Find the bi-node-connected components of an undirected graph.
760 801
  ///
761
  /// This function finds the bi-node-connected components in an undirected
762
  /// graph. The bi-node-connected components are the classes of an equivalence
763
  /// relation on the undirected edges. Two undirected edge are in relationship
764
  /// when they are on same circle.
802
  /// This function finds the bi-node-connected components of the given
803
  /// undirected graph.
804
  ///
805
  /// The bi-node-connected components are the classes of an equivalence
806
  /// relation on the edges of a undirected graph. Two edges are in the
807
  /// same class if they are on same circle.
765 808
  ///
766 809
  /// \image html node_biconnected_components.png
767 810
  /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
768 811
  ///
769
  /// \param graph The graph.
770
  /// \retval compMap A writable uedge map. The values will be set from 0
771
  /// to the number of the biconnected components minus one. Each values
772
  /// of the map will be set exactly once, the values of a certain component
773
  /// will be set continuously.
774
  /// \return The number of components.
812
  /// \param graph The undirected graph.
813
  /// \retval compMap A writable edge map. The values will be set from 0
814
  /// to the number of the bi-node-connected components minus one. Each
815
  /// value of the map will be set exactly once, and the values of a 
816
  /// certain component will be set continuously.
817
  /// \return The number of bi-node-connected components.
818
  ///
819
  /// \see biNodeConnected(), countBiNodeConnectedComponents()
775 820
  template <typename Graph, typename EdgeMap>
776 821
  int biNodeConnectedComponents(const Graph& graph,
777 822
                                EdgeMap& compMap) {
778 823
    checkConcept<concepts::Graph, Graph>();
779 824
    typedef typename Graph::NodeIt NodeIt;
780 825
    typedef typename Graph::Edge Edge;
781 826
    checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
782 827

	
783 828
    using namespace _connectivity_bits;
784 829

	
785 830
    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
786 831

	
787 832
    int compNum = 0;
788 833
    Visitor visitor(graph, compMap, compNum);
789 834

	
790 835
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
791 836
    dfs.init();
792 837

	
793 838
    for (NodeIt it(graph); it != INVALID; ++it) {
794 839
      if (!dfs.reached(it)) {
795 840
        dfs.addSource(it);
796 841
        dfs.start();
797 842
      }
798 843
    }
799 844
    return compNum;
800 845
  }
801 846

	
802 847
  /// \ingroup graph_properties
803 848
  ///
804
  /// \brief Find the bi-node-connected cut nodes.
849
  /// \brief Find the bi-node-connected cut nodes in an undirected graph.
805 850
  ///
806
  /// This function finds the bi-node-connected cut nodes in an undirected
807
  /// graph. The bi-node-connected components are the classes of an equivalence
808
  /// relation on the undirected edges. Two undirected edges are in
809
  /// relationship when they are on same circle. The biconnected components
810
  /// are separted by nodes which are the cut nodes of the components.
851
  /// This function finds the bi-node-connected cut nodes in the given
852
  /// undirected graph.
811 853
  ///
812
  /// \param graph The graph.
813
  /// \retval cutMap A writable edge map. The values will be set true when
814
  /// the node separate two or more components.
854
  /// The bi-node-connected components are the classes of an equivalence
855
  /// relation on the edges of a undirected graph. Two edges are in the
856
  /// same class if they are on same circle.
857
  /// The bi-node-connected components are separted by the cut nodes of
858
  /// the components.
859
  ///
860
  /// \param graph The undirected graph.
861
  /// \retval cutMap A writable node map. The values will be set to 
862
  /// \c true for the nodes that separate two or more components
863
  /// (exactly once for each cut node), and will not be changed for
864
  /// other nodes.
815 865
  /// \return The number of the cut nodes.
866
  ///
867
  /// \see biNodeConnected(), biNodeConnectedComponents()
816 868
  template <typename Graph, typename NodeMap>
817 869
  int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
818 870
    checkConcept<concepts::Graph, Graph>();
819 871
    typedef typename Graph::Node Node;
820 872
    typedef typename Graph::NodeIt NodeIt;
821 873
    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
822 874

	
823 875
    using namespace _connectivity_bits;
824 876

	
825 877
    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
826 878

	
827 879
    int cutNum = 0;
828 880
    Visitor visitor(graph, cutMap, cutNum);
829 881

	
830 882
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
831 883
    dfs.init();
832 884

	
833 885
    for (NodeIt it(graph); it != INVALID; ++it) {
834 886
      if (!dfs.reached(it)) {
835 887
        dfs.addSource(it);
836 888
        dfs.start();
837 889
      }
838 890
    }
839 891
    return cutNum;
840 892
  }
841 893

	
842 894
  namespace _connectivity_bits {
843 895

	
844 896
    template <typename Digraph>
845 897
    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
846 898
    public:
847 899
      typedef typename Digraph::Node Node;
848 900
      typedef typename Digraph::Arc Arc;
849 901
      typedef typename Digraph::Edge Edge;
850 902

	
851 903
      CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
852 904
        : _graph(graph), _compNum(compNum),
853 905
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
854 906

	
855 907
      void start(const Node& node) {
856 908
        _predMap.set(node, INVALID);
857 909
      }
858 910

	
859 911
      void reach(const Node& node) {
860 912
        _numMap.set(node, _num);
861 913
        _retMap.set(node, _num);
862 914
        ++_num;
863 915
      }
864 916

	
865 917
      void leave(const Node& node) {
866 918
        if (_numMap[node] <= _retMap[node]) {
867 919
          ++_compNum;
868 920
        }
869 921
      }
870 922

	
871 923
      void discover(const Arc& edge) {
872 924
        _predMap.set(_graph.target(edge), edge);
873 925
      }
874 926

	
875 927
      void examine(const Arc& edge) {
876 928
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
877 929
          return;
878 930
        }
879 931
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
880 932
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
881 933
        }
882 934
      }
883 935

	
884 936
      void backtrack(const Arc& edge) {
885 937
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
886 938
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
887 939
        }
888 940
      }
889 941

	
890 942
    private:
891 943
      const Digraph& _graph;
892 944
      int& _compNum;
893 945

	
894 946
      typename Digraph::template NodeMap<int> _numMap;
895 947
      typename Digraph::template NodeMap<int> _retMap;
896 948
      typename Digraph::template NodeMap<Arc> _predMap;
897 949
      int _num;
898 950
    };
899 951

	
900 952
    template <typename Digraph, typename NodeMap>
901 953
    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
902 954
    public:
903 955
      typedef typename Digraph::Node Node;
904 956
      typedef typename Digraph::Arc Arc;
905 957
      typedef typename Digraph::Edge Edge;
906 958

	
907 959
      BiEdgeConnectedComponentsVisitor(const Digraph& graph,
908 960
                                       NodeMap& compMap, int &compNum)
909 961
        : _graph(graph), _compMap(compMap), _compNum(compNum),
910 962
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
911 963

	
912 964
      void start(const Node& node) {
913 965
        _predMap.set(node, INVALID);
914 966
      }
915 967

	
916 968
      void reach(const Node& node) {
917 969
        _numMap.set(node, _num);
918 970
        _retMap.set(node, _num);
919 971
        _nodeStack.push(node);
920 972
        ++_num;
921 973
      }
922 974

	
923 975
      void leave(const Node& node) {
924 976
        if (_numMap[node] <= _retMap[node]) {
925 977
          while (_nodeStack.top() != node) {
926 978
            _compMap.set(_nodeStack.top(), _compNum);
927 979
            _nodeStack.pop();
928 980
          }
929 981
          _compMap.set(node, _compNum);
930 982
          _nodeStack.pop();
931 983
          ++_compNum;
932 984
        }
933 985
      }
934 986

	
935 987
      void discover(const Arc& edge) {
936 988
        _predMap.set(_graph.target(edge), edge);
937 989
      }
938 990

	
939 991
      void examine(const Arc& edge) {
940 992
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
941 993
          return;
942 994
        }
943 995
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
944 996
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
945 997
        }
946 998
      }
947 999

	
948 1000
      void backtrack(const Arc& edge) {
949 1001
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
950 1002
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
951 1003
        }
952 1004
      }
953 1005

	
954 1006
    private:
955 1007
      const Digraph& _graph;
956 1008
      NodeMap& _compMap;
957 1009
      int& _compNum;
958 1010

	
959 1011
      typename Digraph::template NodeMap<int> _numMap;
960 1012
      typename Digraph::template NodeMap<int> _retMap;
961 1013
      typename Digraph::template NodeMap<Arc> _predMap;
962 1014
      std::stack<Node> _nodeStack;
963 1015
      int _num;
964 1016
    };
965 1017

	
966 1018

	
967 1019
    template <typename Digraph, typename ArcMap>
968 1020
    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
969 1021
    public:
970 1022
      typedef typename Digraph::Node Node;
971 1023
      typedef typename Digraph::Arc Arc;
972 1024
      typedef typename Digraph::Edge Edge;
973 1025

	
974 1026
      BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
975 1027
                                     ArcMap& cutMap, int &cutNum)
976 1028
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
977 1029
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
978 1030

	
979 1031
      void start(const Node& node) {
980 1032
        _predMap[node] = INVALID;
981 1033
      }
982 1034

	
983 1035
      void reach(const Node& node) {
984 1036
        _numMap.set(node, _num);
985 1037
        _retMap.set(node, _num);
986 1038
        ++_num;
987 1039
      }
988 1040

	
989 1041
      void leave(const Node& node) {
990 1042
        if (_numMap[node] <= _retMap[node]) {
991 1043
          if (_predMap[node] != INVALID) {
992 1044
            _cutMap.set(_predMap[node], true);
993 1045
            ++_cutNum;
994 1046
          }
995 1047
        }
996 1048
      }
997 1049

	
998 1050
      void discover(const Arc& edge) {
999 1051
        _predMap.set(_graph.target(edge), edge);
1000 1052
      }
1001 1053

	
1002 1054
      void examine(const Arc& edge) {
1003 1055
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
1004 1056
          return;
1005 1057
        }
1006 1058
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1007 1059
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1008 1060
        }
1009 1061
      }
1010 1062

	
1011 1063
      void backtrack(const Arc& edge) {
1012 1064
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1013 1065
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1014 1066
        }
1015 1067
      }
1016 1068

	
1017 1069
    private:
1018 1070
      const Digraph& _graph;
1019 1071
      ArcMap& _cutMap;
1020 1072
      int& _cutNum;
1021 1073

	
1022 1074
      typename Digraph::template NodeMap<int> _numMap;
1023 1075
      typename Digraph::template NodeMap<int> _retMap;
1024 1076
      typename Digraph::template NodeMap<Arc> _predMap;
1025 1077
      int _num;
1026 1078
    };
1027 1079
  }
1028 1080

	
1029 1081
  template <typename Graph>
1030 1082
  int countBiEdgeConnectedComponents(const Graph& graph);
1031 1083

	
1032 1084
  /// \ingroup graph_properties
1033 1085
  ///
1034
  /// \brief Checks that the graph is bi-edge-connected.
1086
  /// \brief Check whether an undirected graph is bi-edge-connected.
1035 1087
  ///
1036
  /// This function checks that the graph is bi-edge-connected. The undirected
1037
  /// graph is bi-edge-connected when any two nodes are connected with two
1038
  /// edge-disjoint paths.
1088
  /// This function checks whether the given undirected graph is 
1089
  /// bi-edge-connected, i.e. any two nodes are connected with at least
1090
  /// two edge-disjoint paths.
1039 1091
  ///
1040
  /// \param graph The undirected graph.
1041
  /// \return The number of components.
1092
  /// \return \c true if the graph is bi-edge-connected.
1093
  /// \note By definition, the empty graph is bi-edge-connected.
1094
  ///
1095
  /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
1042 1096
  template <typename Graph>
1043 1097
  bool biEdgeConnected(const Graph& graph) {
1044 1098
    return countBiEdgeConnectedComponents(graph) <= 1;
1045 1099
  }
1046 1100

	
1047 1101
  /// \ingroup graph_properties
1048 1102
  ///
1049
  /// \brief Count the bi-edge-connected components.
1103
  /// \brief Count the number of bi-edge-connected components of an
1104
  /// undirected graph.
1050 1105
  ///
1051
  /// This function count the bi-edge-connected components in an undirected
1052
  /// graph. The bi-edge-connected components are the classes of an equivalence
1053
  /// relation on the nodes. Two nodes are in relationship when they are
1054
  /// connected with at least two edge-disjoint paths.
1106
  /// This function counts the number of bi-edge-connected components of
1107
  /// the given undirected graph.
1055 1108
  ///
1056
  /// \param graph The undirected graph.
1057
  /// \return The number of components.
1109
  /// The bi-edge-connected components are the classes of an equivalence
1110
  /// relation on the nodes of an undirected graph. Two nodes are in the
1111
  /// same class if they are connected with at least two edge-disjoint
1112
  /// paths.
1113
  ///
1114
  /// \return The number of bi-edge-connected components.
1115
  ///
1116
  /// \see biEdgeConnected(), biEdgeConnectedComponents()
1058 1117
  template <typename Graph>
1059 1118
  int countBiEdgeConnectedComponents(const Graph& graph) {
1060 1119
    checkConcept<concepts::Graph, Graph>();
1061 1120
    typedef typename Graph::NodeIt NodeIt;
1062 1121

	
1063 1122
    using namespace _connectivity_bits;
1064 1123

	
1065 1124
    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1066 1125

	
1067 1126
    int compNum = 0;
1068 1127
    Visitor visitor(graph, compNum);
1069 1128

	
1070 1129
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1071 1130
    dfs.init();
1072 1131

	
1073 1132
    for (NodeIt it(graph); it != INVALID; ++it) {
1074 1133
      if (!dfs.reached(it)) {
1075 1134
        dfs.addSource(it);
1076 1135
        dfs.start();
1077 1136
      }
1078 1137
    }
1079 1138
    return compNum;
1080 1139
  }
1081 1140

	
1082 1141
  /// \ingroup graph_properties
1083 1142
  ///
1084
  /// \brief Find the bi-edge-connected components.
1143
  /// \brief Find the bi-edge-connected components of an undirected graph.
1085 1144
  ///
1086
  /// This function finds the bi-edge-connected components in an undirected
1087
  /// graph. The bi-edge-connected components are the classes of an equivalence
1088
  /// relation on the nodes. Two nodes are in relationship when they are
1089
  /// connected at least two edge-disjoint paths.
1145
  /// This function finds the bi-edge-connected components of the given
1146
  /// undirected graph.
1147
  ///
1148
  /// The bi-edge-connected components are the classes of an equivalence
1149
  /// relation on the nodes of an undirected graph. Two nodes are in the
1150
  /// same class if they are connected with at least two edge-disjoint
1151
  /// paths.
1090 1152
  ///
1091 1153
  /// \image html edge_biconnected_components.png
1092 1154
  /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
1093 1155
  ///
1094
  /// \param graph The graph.
1156
  /// \param graph The undirected graph.
1095 1157
  /// \retval compMap A writable node map. The values will be set from 0 to
1096
  /// the number of the biconnected components minus one. Each values
1097
  /// of the map will be set exactly once, the values of a certain component
1098
  /// will be set continuously.
1099
  /// \return The number of components.
1158
  /// the number of the bi-edge-connected components minus one. Each value
1159
  /// of the map will be set exactly once, and the values of a certain
1160
  /// component will be set continuously.
1161
  /// \return The number of bi-edge-connected components.
1162
  ///
1163
  /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
1100 1164
  template <typename Graph, typename NodeMap>
1101 1165
  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
1102 1166
    checkConcept<concepts::Graph, Graph>();
1103 1167
    typedef typename Graph::NodeIt NodeIt;
1104 1168
    typedef typename Graph::Node Node;
1105 1169
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1106 1170

	
1107 1171
    using namespace _connectivity_bits;
1108 1172

	
1109 1173
    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1110 1174

	
1111 1175
    int compNum = 0;
1112 1176
    Visitor visitor(graph, compMap, compNum);
1113 1177

	
1114 1178
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1115 1179
    dfs.init();
1116 1180

	
1117 1181
    for (NodeIt it(graph); it != INVALID; ++it) {
1118 1182
      if (!dfs.reached(it)) {
1119 1183
        dfs.addSource(it);
1120 1184
        dfs.start();
1121 1185
      }
1122 1186
    }
1123 1187
    return compNum;
1124 1188
  }
1125 1189

	
1126 1190
  /// \ingroup graph_properties
1127 1191
  ///
1128
  /// \brief Find the bi-edge-connected cut edges.
1192
  /// \brief Find the bi-edge-connected cut edges in an undirected graph.
1129 1193
  ///
1130
  /// This function finds the bi-edge-connected components in an undirected
1131
  /// graph. The bi-edge-connected components are the classes of an equivalence
1132
  /// relation on the nodes. Two nodes are in relationship when they are
1133
  /// connected with at least two edge-disjoint paths. The bi-edge-connected
1134
  /// components are separted by edges which are the cut edges of the
1135
  /// components.
1194
  /// This function finds the bi-edge-connected cut edges in the given
1195
  /// undirected graph. 
1136 1196
  ///
1137
  /// \param graph The graph.
1138
  /// \retval cutMap A writable node map. The values will be set true when the
1139
  /// edge is a cut edge.
1197
  /// The bi-edge-connected components are the classes of an equivalence
1198
  /// relation on the nodes of an undirected graph. Two nodes are in the
1199
  /// same class if they are connected with at least two edge-disjoint
1200
  /// paths.
1201
  /// The bi-edge-connected components are separted by the cut edges of
1202
  /// the components.
1203
  ///
1204
  /// \param graph The undirected graph.
1205
  /// \retval cutMap A writable edge map. The values will be set to \c true
1206
  /// for the cut edges (exactly once for each cut edge), and will not be
1207
  /// changed for other edges.
1140 1208
  /// \return The number of cut edges.
1209
  ///
1210
  /// \see biEdgeConnected(), biEdgeConnectedComponents()
1141 1211
  template <typename Graph, typename EdgeMap>
1142 1212
  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
1143 1213
    checkConcept<concepts::Graph, Graph>();
1144 1214
    typedef typename Graph::NodeIt NodeIt;
1145 1215
    typedef typename Graph::Edge Edge;
1146 1216
    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
1147 1217

	
1148 1218
    using namespace _connectivity_bits;
1149 1219

	
1150 1220
    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1151 1221

	
1152 1222
    int cutNum = 0;
1153 1223
    Visitor visitor(graph, cutMap, cutNum);
1154 1224

	
1155 1225
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1156 1226
    dfs.init();
1157 1227

	
1158 1228
    for (NodeIt it(graph); it != INVALID; ++it) {
1159 1229
      if (!dfs.reached(it)) {
1160 1230
        dfs.addSource(it);
1161 1231
        dfs.start();
1162 1232
      }
1163 1233
    }
1164 1234
    return cutNum;
1165 1235
  }
1166 1236

	
1167 1237

	
1168 1238
  namespace _connectivity_bits {
1169 1239

	
1170 1240
    template <typename Digraph, typename IntNodeMap>
1171 1241
    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
1172 1242
    public:
1173 1243
      typedef typename Digraph::Node Node;
1174 1244
      typedef typename Digraph::Arc edge;
1175 1245

	
1176 1246
      TopologicalSortVisitor(IntNodeMap& order, int num)
1177 1247
        : _order(order), _num(num) {}
1178 1248

	
1179 1249
      void leave(const Node& node) {
1180 1250
        _order.set(node, --_num);
1181 1251
      }
1182 1252

	
1183 1253
    private:
1184 1254
      IntNodeMap& _order;
1185 1255
      int _num;
1186 1256
    };
1187 1257

	
1188 1258
  }
1189 1259

	
1190 1260
  /// \ingroup graph_properties
1191 1261
  ///
1262
  /// \brief Check whether a digraph is DAG.
1263
  ///
1264
  /// This function checks whether the given digraph is DAG, i.e.
1265
  /// \e Directed \e Acyclic \e Graph.
1266
  /// \return \c true if there is no directed cycle in the digraph.
1267
  /// \see acyclic()
1268
  template <typename Digraph>
1269
  bool dag(const Digraph& digraph) {
1270

	
1271
    checkConcept<concepts::Digraph, Digraph>();
1272

	
1273
    typedef typename Digraph::Node Node;
1274
    typedef typename Digraph::NodeIt NodeIt;
1275
    typedef typename Digraph::Arc Arc;
1276

	
1277
    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1278

	
1279
    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1280
      Create dfs(digraph);
1281

	
1282
    ProcessedMap processed(digraph);
1283
    dfs.processedMap(processed);
1284

	
1285
    dfs.init();
1286
    for (NodeIt it(digraph); it != INVALID; ++it) {
1287
      if (!dfs.reached(it)) {
1288
        dfs.addSource(it);
1289
        while (!dfs.emptyQueue()) {
1290
          Arc arc = dfs.nextArc();
1291
          Node target = digraph.target(arc);
1292
          if (dfs.reached(target) && !processed[target]) {
1293
            return false;
1294
          }
1295
          dfs.processNextArc();
1296
        }
1297
      }
1298
    }
1299
    return true;
1300
  }
1301

	
1302
  /// \ingroup graph_properties
1303
  ///
1192 1304
  /// \brief Sort the nodes of a DAG into topolgical order.
1193 1305
  ///
1194
  /// Sort the nodes of a DAG into topolgical order.
1306
  /// This function sorts the nodes of the given acyclic digraph (DAG)
1307
  /// into topolgical order.
1195 1308
  ///
1196
  /// \param graph The graph. It must be directed and acyclic.
1309
  /// \param digraph The digraph, which must be DAG.
1197 1310
  /// \retval order A writable node map. The values will be set from 0 to
1198
  /// the number of the nodes in the graph minus one. Each values of the map
1199
  /// will be set exactly once, the values  will be set descending order.
1311
  /// the number of the nodes in the digraph minus one. Each value of the
1312
  /// map will be set exactly once, and the values will be set descending
1313
  /// order.
1200 1314
  ///
1201
  /// \see checkedTopologicalSort
1202
  /// \see dag
1315
  /// \see dag(), checkedTopologicalSort()
1203 1316
  template <typename Digraph, typename NodeMap>
1204
  void topologicalSort(const Digraph& graph, NodeMap& order) {
1317
  void topologicalSort(const Digraph& digraph, NodeMap& order) {
1205 1318
    using namespace _connectivity_bits;
1206 1319

	
1207 1320
    checkConcept<concepts::Digraph, Digraph>();
1208 1321
    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
1209 1322

	
1210 1323
    typedef typename Digraph::Node Node;
1211 1324
    typedef typename Digraph::NodeIt NodeIt;
1212 1325
    typedef typename Digraph::Arc Arc;
1213 1326

	
1214 1327
    TopologicalSortVisitor<Digraph, NodeMap>
1215
      visitor(order, countNodes(graph));
1328
      visitor(order, countNodes(digraph));
1216 1329

	
1217 1330
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1218
      dfs(graph, visitor);
1331
      dfs(digraph, visitor);
1219 1332

	
1220 1333
    dfs.init();
1221
    for (NodeIt it(graph); it != INVALID; ++it) {
1334
    for (NodeIt it(digraph); it != INVALID; ++it) {
1222 1335
      if (!dfs.reached(it)) {
1223 1336
        dfs.addSource(it);
1224 1337
        dfs.start();
1225 1338
      }
1226 1339
    }
1227 1340
  }
1228 1341

	
1229 1342
  /// \ingroup graph_properties
1230 1343
  ///
1231 1344
  /// \brief Sort the nodes of a DAG into topolgical order.
1232 1345
  ///
1233
  /// Sort the nodes of a DAG into topolgical order. It also checks
1234
  /// that the given graph is DAG.
1346
  /// This function sorts the nodes of the given acyclic digraph (DAG)
1347
  /// into topolgical order and also checks whether the given digraph
1348
  /// is DAG.
1235 1349
  ///
1236
  /// \param digraph The graph. It must be directed and acyclic.
1237
  /// \retval order A readable - writable node map. The values will be set
1238
  /// from 0 to the number of the nodes in the graph minus one. Each values
1239
  /// of the map will be set exactly once, the values will be set descending
1240
  /// order.
1241
  /// \return \c false when the graph is not DAG.
1350
  /// \param digraph The digraph.
1351
  /// \retval order A readable and writable node map. The values will be
1352
  /// set from 0 to the number of the nodes in the digraph minus one. 
1353
  /// Each value of the map will be set exactly once, and the values will
1354
  /// be set descending order.
1355
  /// \return \c false if the digraph is not DAG.
1242 1356
  ///
1243
  /// \see topologicalSort
1244
  /// \see dag
1357
  /// \see dag(), topologicalSort()
1245 1358
  template <typename Digraph, typename NodeMap>
1246 1359
  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
1247 1360
    using namespace _connectivity_bits;
1248 1361

	
1249 1362
    checkConcept<concepts::Digraph, Digraph>();
1250 1363
    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
1251 1364
      NodeMap>();
1252 1365

	
1253 1366
    typedef typename Digraph::Node Node;
1254 1367
    typedef typename Digraph::NodeIt NodeIt;
1255 1368
    typedef typename Digraph::Arc Arc;
1256 1369

	
1257 1370
    for (NodeIt it(digraph); it != INVALID; ++it) {
1258 1371
      order.set(it, -1);
1259 1372
    }
1260 1373

	
1261 1374
    TopologicalSortVisitor<Digraph, NodeMap>
1262 1375
      visitor(order, countNodes(digraph));
1263 1376

	
1264 1377
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1265 1378
      dfs(digraph, visitor);
1266 1379

	
1267 1380
    dfs.init();
1268 1381
    for (NodeIt it(digraph); it != INVALID; ++it) {
1269 1382
      if (!dfs.reached(it)) {
1270 1383
        dfs.addSource(it);
1271 1384
        while (!dfs.emptyQueue()) {
1272 1385
           Arc arc = dfs.nextArc();
1273 1386
           Node target = digraph.target(arc);
1274 1387
           if (dfs.reached(target) && order[target] == -1) {
1275 1388
             return false;
1276 1389
           }
1277 1390
           dfs.processNextArc();
1278 1391
         }
1279 1392
      }
1280 1393
    }
1281 1394
    return true;
1282 1395
  }
1283 1396

	
1284 1397
  /// \ingroup graph_properties
1285 1398
  ///
1286
  /// \brief Check that the given directed graph is a DAG.
1399
  /// \brief Check whether an undirected graph is acyclic.
1287 1400
  ///
1288
  /// Check that the given directed graph is a DAG. The DAG is
1289
  /// an Directed Acyclic Digraph.
1290
  /// \return \c false when the graph is not DAG.
1291
  /// \see acyclic
1292
  template <typename Digraph>
1293
  bool dag(const Digraph& digraph) {
1294

	
1295
    checkConcept<concepts::Digraph, Digraph>();
1296

	
1297
    typedef typename Digraph::Node Node;
1298
    typedef typename Digraph::NodeIt NodeIt;
1299
    typedef typename Digraph::Arc Arc;
1300

	
1301
    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1302

	
1303
    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1304
      Create dfs(digraph);
1305

	
1306
    ProcessedMap processed(digraph);
1307
    dfs.processedMap(processed);
1308

	
1309
    dfs.init();
1310
    for (NodeIt it(digraph); it != INVALID; ++it) {
1311
      if (!dfs.reached(it)) {
1312
        dfs.addSource(it);
1313
        while (!dfs.emptyQueue()) {
1314
          Arc edge = dfs.nextArc();
1315
          Node target = digraph.target(edge);
1316
          if (dfs.reached(target) && !processed[target]) {
1317
            return false;
1318
          }
1319
          dfs.processNextArc();
1320
        }
1321
      }
1322
    }
1323
    return true;
1324
  }
1325

	
1326
  /// \ingroup graph_properties
1327
  ///
1328
  /// \brief Check that the given undirected graph is acyclic.
1329
  ///
1330
  /// Check that the given undirected graph acyclic.
1331
  /// \param graph The undirected graph.
1332
  /// \return \c true when there is no circle in the graph.
1333
  /// \see dag
1401
  /// This function checks whether the given undirected graph is acyclic.
1402
  /// \return \c true if there is no cycle in the graph.
1403
  /// \see dag()
1334 1404
  template <typename Graph>
1335 1405
  bool acyclic(const Graph& graph) {
1336 1406
    checkConcept<concepts::Graph, Graph>();
1337 1407
    typedef typename Graph::Node Node;
1338 1408
    typedef typename Graph::NodeIt NodeIt;
1339 1409
    typedef typename Graph::Arc Arc;
1340 1410
    Dfs<Graph> dfs(graph);
1341 1411
    dfs.init();
1342 1412
    for (NodeIt it(graph); it != INVALID; ++it) {
1343 1413
      if (!dfs.reached(it)) {
1344 1414
        dfs.addSource(it);
1345 1415
        while (!dfs.emptyQueue()) {
1346
          Arc edge = dfs.nextArc();
1347
          Node source = graph.source(edge);
1348
          Node target = graph.target(edge);
1416
          Arc arc = dfs.nextArc();
1417
          Node source = graph.source(arc);
1418
          Node target = graph.target(arc);
1349 1419
          if (dfs.reached(target) &&
1350
              dfs.predArc(source) != graph.oppositeArc(edge)) {
1420
              dfs.predArc(source) != graph.oppositeArc(arc)) {
1351 1421
            return false;
1352 1422
          }
1353 1423
          dfs.processNextArc();
1354 1424
        }
1355 1425
      }
1356 1426
    }
1357 1427
    return true;
1358 1428
  }
1359 1429

	
1360 1430
  /// \ingroup graph_properties
1361 1431
  ///
1362
  /// \brief Check that the given undirected graph is tree.
1432
  /// \brief Check whether an undirected graph is tree.
1363 1433
  ///
1364
  /// Check that the given undirected graph is tree.
1365
  /// \param graph The undirected graph.
1366
  /// \return \c true when the graph is acyclic and connected.
1434
  /// This function checks whether the given undirected graph is tree.
1435
  /// \return \c true if the graph is acyclic and connected.
1436
  /// \see acyclic(), connected()
1367 1437
  template <typename Graph>
1368 1438
  bool tree(const Graph& graph) {
1369 1439
    checkConcept<concepts::Graph, Graph>();
1370 1440
    typedef typename Graph::Node Node;
1371 1441
    typedef typename Graph::NodeIt NodeIt;
1372 1442
    typedef typename Graph::Arc Arc;
1373 1443
    if (NodeIt(graph) == INVALID) return true;
1374 1444
    Dfs<Graph> dfs(graph);
1375 1445
    dfs.init();
1376 1446
    dfs.addSource(NodeIt(graph));
1377 1447
    while (!dfs.emptyQueue()) {
1378
      Arc edge = dfs.nextArc();
1379
      Node source = graph.source(edge);
1380
      Node target = graph.target(edge);
1448
      Arc arc = dfs.nextArc();
1449
      Node source = graph.source(arc);
1450
      Node target = graph.target(arc);
1381 1451
      if (dfs.reached(target) &&
1382
          dfs.predArc(source) != graph.oppositeArc(edge)) {
1452
          dfs.predArc(source) != graph.oppositeArc(arc)) {
1383 1453
        return false;
1384 1454
      }
1385 1455
      dfs.processNextArc();
1386 1456
    }
1387 1457
    for (NodeIt it(graph); it != INVALID; ++it) {
1388 1458
      if (!dfs.reached(it)) {
1389 1459
        return false;
1390 1460
      }
1391 1461
    }
1392 1462
    return true;
1393 1463
  }
1394 1464

	
1395 1465
  namespace _connectivity_bits {
1396 1466

	
1397 1467
    template <typename Digraph>
1398 1468
    class BipartiteVisitor : public BfsVisitor<Digraph> {
1399 1469
    public:
1400 1470
      typedef typename Digraph::Arc Arc;
1401 1471
      typedef typename Digraph::Node Node;
1402 1472

	
1403 1473
      BipartiteVisitor(const Digraph& graph, bool& bipartite)
1404 1474
        : _graph(graph), _part(graph), _bipartite(bipartite) {}
1405 1475

	
1406 1476
      void start(const Node& node) {
1407 1477
        _part[node] = true;
1408 1478
      }
1409 1479
      void discover(const Arc& edge) {
1410 1480
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1411 1481
      }
1412 1482
      void examine(const Arc& edge) {
1413 1483
        _bipartite = _bipartite &&
1414 1484
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1415 1485
      }
1416 1486

	
1417 1487
    private:
1418 1488

	
1419 1489
      const Digraph& _graph;
1420 1490
      typename Digraph::template NodeMap<bool> _part;
1421 1491
      bool& _bipartite;
1422 1492
    };
1423 1493

	
1424 1494
    template <typename Digraph, typename PartMap>
1425 1495
    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
1426 1496
    public:
1427 1497
      typedef typename Digraph::Arc Arc;
1428 1498
      typedef typename Digraph::Node Node;
1429 1499

	
1430 1500
      BipartitePartitionsVisitor(const Digraph& graph,
1431 1501
                                 PartMap& part, bool& bipartite)
1432 1502
        : _graph(graph), _part(part), _bipartite(bipartite) {}
1433 1503

	
1434 1504
      void start(const Node& node) {
1435 1505
        _part.set(node, true);
1436 1506
      }
1437 1507
      void discover(const Arc& edge) {
1438 1508
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1439 1509
      }
1440 1510
      void examine(const Arc& edge) {
1441 1511
        _bipartite = _bipartite &&
1442 1512
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1443 1513
      }
1444 1514

	
1445 1515
    private:
1446 1516

	
1447 1517
      const Digraph& _graph;
1448 1518
      PartMap& _part;
1449 1519
      bool& _bipartite;
1450 1520
    };
1451 1521
  }
1452 1522

	
1453 1523
  /// \ingroup graph_properties
1454 1524
  ///
1455
  /// \brief Check if the given undirected graph is bipartite or not
1525
  /// \brief Check whether an undirected graph is bipartite.
1456 1526
  ///
1457
  /// The function checks if the given undirected \c graph graph is bipartite
1458
  /// or not. The \ref Bfs algorithm is used to calculate the result.
1459
  /// \param graph The undirected graph.
1460
  /// \return \c true if \c graph is bipartite, \c false otherwise.
1461
  /// \sa bipartitePartitions
1527
  /// The function checks whether the given undirected graph is bipartite.
1528
  /// \return \c true if the graph is bipartite.
1529
  ///
1530
  /// \see bipartitePartitions()
1462 1531
  template<typename Graph>
1463
  inline bool bipartite(const Graph &graph){
1532
  bool bipartite(const Graph &graph){
1464 1533
    using namespace _connectivity_bits;
1465 1534

	
1466 1535
    checkConcept<concepts::Graph, Graph>();
1467 1536

	
1468 1537
    typedef typename Graph::NodeIt NodeIt;
1469 1538
    typedef typename Graph::ArcIt ArcIt;
1470 1539

	
1471 1540
    bool bipartite = true;
1472 1541

	
1473 1542
    BipartiteVisitor<Graph>
1474 1543
      visitor(graph, bipartite);
1475 1544
    BfsVisit<Graph, BipartiteVisitor<Graph> >
1476 1545
      bfs(graph, visitor);
1477 1546
    bfs.init();
1478 1547
    for(NodeIt it(graph); it != INVALID; ++it) {
1479 1548
      if(!bfs.reached(it)){
1480 1549
        bfs.addSource(it);
1481 1550
        while (!bfs.emptyQueue()) {
1482 1551
          bfs.processNextNode();
1483 1552
          if (!bipartite) return false;
1484 1553
        }
1485 1554
      }
1486 1555
    }
1487 1556
    return true;
1488 1557
  }
1489 1558

	
1490 1559
  /// \ingroup graph_properties
1491 1560
  ///
1492
  /// \brief Check if the given undirected graph is bipartite or not
1561
  /// \brief Find the bipartite partitions of an undirected graph.
1493 1562
  ///
1494
  /// The function checks if the given undirected graph is bipartite
1495
  /// or not. The  \ref  Bfs  algorithm  is   used  to  calculate the result.
1496
  /// During the execution, the \c partMap will be set as the two
1497
  /// partitions of the graph.
1563
  /// This function checks whether the given undirected graph is bipartite
1564
  /// and gives back the bipartite partitions.
1498 1565
  ///
1499 1566
  /// \image html bipartite_partitions.png
1500 1567
  /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
1501 1568
  ///
1502 1569
  /// \param graph The undirected graph.
1503
  /// \retval partMap A writable bool map of nodes. It will be set as the
1504
  /// two partitions of the graph.
1505
  /// \return \c true if \c graph is bipartite, \c false otherwise.
1570
  /// \retval partMap A writable node map of \c bool (or convertible) value
1571
  /// type. The values will be set to \c true for one component and
1572
  /// \c false for the other one.
1573
  /// \return \c true if the graph is bipartite, \c false otherwise.
1574
  ///
1575
  /// \see bipartite()
1506 1576
  template<typename Graph, typename NodeMap>
1507
  inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
1577
  bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
1508 1578
    using namespace _connectivity_bits;
1509 1579

	
1510 1580
    checkConcept<concepts::Graph, Graph>();
1581
    checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
1511 1582

	
1512 1583
    typedef typename Graph::Node Node;
1513 1584
    typedef typename Graph::NodeIt NodeIt;
1514 1585
    typedef typename Graph::ArcIt ArcIt;
1515 1586

	
1516 1587
    bool bipartite = true;
1517 1588

	
1518 1589
    BipartitePartitionsVisitor<Graph, NodeMap>
1519 1590
      visitor(graph, partMap, bipartite);
1520 1591
    BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
1521 1592
      bfs(graph, visitor);
1522 1593
    bfs.init();
1523 1594
    for(NodeIt it(graph); it != INVALID; ++it) {
1524 1595
      if(!bfs.reached(it)){
1525 1596
        bfs.addSource(it);
1526 1597
        while (!bfs.emptyQueue()) {
1527 1598
          bfs.processNextNode();
1528 1599
          if (!bipartite) return false;
1529 1600
        }
1530 1601
      }
1531 1602
    }
1532 1603
    return true;
1533 1604
  }
1534 1605

	
1535
  /// \brief Returns true when there are not loop edges in the graph.
1606
  /// \ingroup graph_properties
1536 1607
  ///
1537
  /// Returns true when there are not loop edges in the graph.
1538
  template <typename Digraph>
1539
  bool loopFree(const Digraph& digraph) {
1540
    for (typename Digraph::ArcIt it(digraph); it != INVALID; ++it) {
1541
      if (digraph.source(it) == digraph.target(it)) return false;
1608
  /// \brief Check whether the given graph contains no loop arcs/edges.
1609
  ///
1610
  /// This function returns \c true if there are no loop arcs/edges in
1611
  /// the given graph. It works for both directed and undirected graphs.
1612
  template <typename Graph>
1613
  bool loopFree(const Graph& graph) {
1614
    for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
1615
      if (graph.source(it) == graph.target(it)) return false;
1542 1616
    }
1543 1617
    return true;
1544 1618
  }
1545 1619

	
1546
  /// \brief Returns true when there are not parallel edges in the graph.
1620
  /// \ingroup graph_properties
1547 1621
  ///
1548
  /// Returns true when there are not parallel edges in the graph.
1622
  /// \brief Check whether the given graph contains no parallel arcs/edges.
1623
  ///
1624
  /// This function returns \c true if there are no parallel arcs/edges in
1625
  /// the given graph. It works for both directed and undirected graphs.
1549 1626
  template <typename Graph>
1550 1627
  bool parallelFree(const Graph& graph) {
1551 1628
    typename Graph::template NodeMap<int> reached(graph, 0);
1552 1629
    int cnt = 1;
1553 1630
    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1554 1631
      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
1555 1632
        if (reached[graph.target(a)] == cnt) return false;
1556 1633
        reached[graph.target(a)] = cnt;
1557 1634
      }
1558 1635
      ++cnt;
1559 1636
    }
1560 1637
    return true;
1561 1638
  }
1562 1639

	
1563
  /// \brief Returns true when there are not loop edges and parallel
1564
  /// edges in the graph.
1640
  /// \ingroup graph_properties
1565 1641
  ///
1566
  /// Returns true when there are not loop edges and parallel edges in
1567
  /// the graph.
1642
  /// \brief Check whether the given graph is simple.
1643
  ///
1644
  /// This function returns \c true if the given graph is simple, i.e.
1645
  /// it contains no loop arcs/edges and no parallel arcs/edges.
1646
  /// The function works for both directed and undirected graphs.
1647
  /// \see loopFree(), parallelFree()
1568 1648
  template <typename Graph>
1569 1649
  bool simpleGraph(const Graph& graph) {
1570 1650
    typename Graph::template NodeMap<int> reached(graph, 0);
1571 1651
    int cnt = 1;
1572 1652
    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1573 1653
      reached[n] = cnt;
1574 1654
      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
1575 1655
        if (reached[graph.target(a)] == cnt) return false;
1576 1656
        reached[graph.target(a)] = cnt;
1577 1657
      }
1578 1658
      ++cnt;
1579 1659
    }
1580 1660
    return true;
1581 1661
  }
1582 1662

	
1583 1663
} //namespace lemon
1584 1664

	
1585 1665
#endif //LEMON_CONNECTIVITY_H
Show white space 34359738368 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-2009
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 19
#ifndef LEMON_EULER_H
20 20
#define LEMON_EULER_H
21 21

	
22 22
#include<lemon/core.h>
23 23
#include<lemon/adaptors.h>
24 24
#include<lemon/connectivity.h>
25 25
#include <list>
26 26

	
27 27
/// \ingroup graph_properties
28 28
/// \file
29 29
/// \brief Euler tour iterators and a function for checking the \e Eulerian 
30 30
/// property.
31 31
///
32 32
///This file provides Euler tour iterators and a function to check
33 33
///if a (di)graph is \e Eulerian.
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  ///Euler tour iterator for digraphs.
38 38

	
39 39
  /// \ingroup graph_prop
40 40
  ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
41 41
  ///graph (if there exists) and it converts to the \c Arc type of the digraph.
42 42
  ///
43 43
  ///For example, if the given digraph has an Euler tour (i.e it has only one
44 44
  ///non-trivial component and the in-degree is equal to the out-degree 
45 45
  ///for all nodes), then the following code will put the arcs of \c g
46 46
  ///to the vector \c et according to an Euler tour of \c g.
47 47
  ///\code
48 48
  ///  std::vector<ListDigraph::Arc> et;
49 49
  ///  for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
50 50
  ///    et.push_back(e);
51 51
  ///\endcode
52 52
  ///If \c g has no Euler tour, then the resulted walk will not be closed
53 53
  ///or not contain all arcs.
54 54
  ///\sa EulerIt
55 55
  template<typename GR>
56 56
  class DiEulerIt
57 57
  {
58 58
    typedef typename GR::Node Node;
59 59
    typedef typename GR::NodeIt NodeIt;
60 60
    typedef typename GR::Arc Arc;
61 61
    typedef typename GR::ArcIt ArcIt;
62 62
    typedef typename GR::OutArcIt OutArcIt;
63 63
    typedef typename GR::InArcIt InArcIt;
64 64

	
65 65
    const GR &g;
66 66
    typename GR::template NodeMap<OutArcIt> narc;
67 67
    std::list<Arc> euler;
68 68

	
69 69
  public:
70 70

	
71 71
    ///Constructor
72 72

	
73 73
    ///Constructor.
74 74
    ///\param gr A digraph.
75 75
    ///\param start The starting point of the tour. If it is not given,
76 76
    ///the tour will start from the first node that has an outgoing arc.
77 77
    DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
78 78
      : g(gr), narc(g)
79 79
    {
80 80
      if (start==INVALID) {
81 81
        NodeIt n(g);
82 82
        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
83 83
        start=n;
84 84
      }
85 85
      if (start!=INVALID) {
86 86
        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
87 87
        while (narc[start]!=INVALID) {
88 88
          euler.push_back(narc[start]);
89 89
          Node next=g.target(narc[start]);
90 90
          ++narc[start];
91 91
          start=next;
92 92
        }
93 93
      }
94 94
    }
95 95

	
96 96
    ///Arc conversion
97 97
    operator Arc() { return euler.empty()?INVALID:euler.front(); }
98 98
    ///Compare with \c INVALID
99 99
    bool operator==(Invalid) { return euler.empty(); }
100 100
    ///Compare with \c INVALID
101 101
    bool operator!=(Invalid) { return !euler.empty(); }
102 102

	
103 103
    ///Next arc of the tour
104 104

	
105 105
    ///Next arc of the tour
106 106
    ///
107 107
    DiEulerIt &operator++() {
108 108
      Node s=g.target(euler.front());
109 109
      euler.pop_front();
110 110
      typename std::list<Arc>::iterator next=euler.begin();
111 111
      while(narc[s]!=INVALID) {
112 112
        euler.insert(next,narc[s]);
113 113
        Node n=g.target(narc[s]);
114 114
        ++narc[s];
115 115
        s=n;
116 116
      }
117 117
      return *this;
118 118
    }
119 119
    ///Postfix incrementation
120 120

	
121 121
    /// Postfix incrementation.
122 122
    ///
123 123
    ///\warning This incrementation
124 124
    ///returns an \c Arc, not a \ref DiEulerIt, as one may
125 125
    ///expect.
126 126
    Arc operator++(int)
127 127
    {
128 128
      Arc e=*this;
129 129
      ++(*this);
130 130
      return e;
131 131
    }
132 132
  };
133 133

	
134 134
  ///Euler tour iterator for graphs.
135 135

	
136 136
  /// \ingroup graph_properties
137 137
  ///This iterator provides an Euler tour (Eulerian circuit) of an
138 138
  ///\e undirected graph (if there exists) and it converts to the \c Arc
139 139
  ///and \c Edge types of the graph.
140 140
  ///
141 141
  ///For example, if the given graph has an Euler tour (i.e it has only one 
142 142
  ///non-trivial component and the degree of each node is even),
143 143
  ///the following code will print the arc IDs according to an
144 144
  ///Euler tour of \c g.
145 145
  ///\code
146 146
  ///  for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
147 147
  ///    std::cout << g.id(Edge(e)) << std::eol;
148 148
  ///  }
149 149
  ///\endcode
150 150
  ///Although this iterator is for undirected graphs, it still returns 
151 151
  ///arcs in order to indicate the direction of the tour.
152 152
  ///(But arcs convert to edges, of course.)
153 153
  ///
154 154
  ///If \c g has no Euler tour, then the resulted walk will not be closed
155 155
  ///or not contain all edges.
156 156
  template<typename GR>
157 157
  class EulerIt
158 158
  {
159 159
    typedef typename GR::Node Node;
160 160
    typedef typename GR::NodeIt NodeIt;
161 161
    typedef typename GR::Arc Arc;
162 162
    typedef typename GR::Edge Edge;
163 163
    typedef typename GR::ArcIt ArcIt;
164 164
    typedef typename GR::OutArcIt OutArcIt;
165 165
    typedef typename GR::InArcIt InArcIt;
166 166

	
167 167
    const GR &g;
168 168
    typename GR::template NodeMap<OutArcIt> narc;
169 169
    typename GR::template EdgeMap<bool> visited;
170 170
    std::list<Arc> euler;
171 171

	
172 172
  public:
173 173

	
174 174
    ///Constructor
175 175

	
176 176
    ///Constructor.
177 177
    ///\param gr A graph.
178 178
    ///\param start The starting point of the tour. If it is not given,
179 179
    ///the tour will start from the first node that has an incident edge.
180 180
    EulerIt(const GR &gr, typename GR::Node start = INVALID)
181 181
      : g(gr), narc(g), visited(g, false)
182 182
    {
183 183
      if (start==INVALID) {
184 184
        NodeIt n(g);
185 185
        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
186 186
        start=n;
187 187
      }
188 188
      if (start!=INVALID) {
189 189
        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
190 190
        while(narc[start]!=INVALID) {
191 191
          euler.push_back(narc[start]);
192 192
          visited[narc[start]]=true;
193 193
          Node next=g.target(narc[start]);
194 194
          ++narc[start];
195 195
          start=next;
196 196
          while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
197 197
        }
198 198
      }
199 199
    }
200 200

	
201 201
    ///Arc conversion
202 202
    operator Arc() const { return euler.empty()?INVALID:euler.front(); }
203 203
    ///Edge conversion
204 204
    operator Edge() const { return euler.empty()?INVALID:euler.front(); }
205 205
    ///Compare with \c INVALID
206 206
    bool operator==(Invalid) const { return euler.empty(); }
207 207
    ///Compare with \c INVALID
208 208
    bool operator!=(Invalid) const { return !euler.empty(); }
209 209

	
210 210
    ///Next arc of the tour
211 211

	
212 212
    ///Next arc of the tour
213 213
    ///
214 214
    EulerIt &operator++() {
215 215
      Node s=g.target(euler.front());
216 216
      euler.pop_front();
217 217
      typename std::list<Arc>::iterator next=euler.begin();
218 218
      while(narc[s]!=INVALID) {
219 219
        while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
220 220
        if(narc[s]==INVALID) break;
221 221
        else {
222 222
          euler.insert(next,narc[s]);
223 223
          visited[narc[s]]=true;
224 224
          Node n=g.target(narc[s]);
225 225
          ++narc[s];
226 226
          s=n;
227 227
        }
228 228
      }
229 229
      return *this;
230 230
    }
231 231

	
232 232
    ///Postfix incrementation
233 233

	
234 234
    /// Postfix incrementation.
235 235
    ///
236 236
    ///\warning This incrementation returns an \c Arc (which converts to 
237 237
    ///an \c Edge), not an \ref EulerIt, as one may expect.
238 238
    Arc operator++(int)
239 239
    {
240 240
      Arc e=*this;
241 241
      ++(*this);
242 242
      return e;
243 243
    }
244 244
  };
245 245

	
246 246

	
247
  ///Check if the given graph is \e Eulerian
247
  ///Check if the given graph is Eulerian
248 248

	
249 249
  /// \ingroup graph_properties
250
  ///This function checks if the given graph is \e Eulerian.
250
  ///This function checks if the given graph is Eulerian.
251 251
  ///It works for both directed and undirected graphs.
252 252
  ///
253 253
  ///By definition, a digraph is called \e Eulerian if
254 254
  ///and only if it is connected and the number of incoming and outgoing
255 255
  ///arcs are the same for each node.
256 256
  ///Similarly, an undirected graph is called \e Eulerian if
257 257
  ///and only if it is connected and the number of incident edges is even
258 258
  ///for each node.
259 259
  ///
260 260
  ///\note There are (di)graphs that are not Eulerian, but still have an
261 261
  /// Euler tour, since they may contain isolated nodes.
262 262
  ///
263 263
  ///\sa DiEulerIt, EulerIt
264 264
  template<typename GR>
265 265
#ifdef DOXYGEN
266 266
  bool
267 267
#else
268 268
  typename enable_if<UndirectedTagIndicator<GR>,bool>::type
269 269
  eulerian(const GR &g)
270 270
  {
271 271
    for(typename GR::NodeIt n(g);n!=INVALID;++n)
272 272
      if(countIncEdges(g,n)%2) return false;
273 273
    return connected(g);
274 274
  }
275 275
  template<class GR>
276 276
  typename disable_if<UndirectedTagIndicator<GR>,bool>::type
277 277
#endif
278 278
  eulerian(const GR &g)
279 279
  {
280 280
    for(typename GR::NodeIt n(g);n!=INVALID;++n)
281 281
      if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
282 282
    return connected(undirector(g));
283 283
  }
284 284

	
285 285
}
286 286

	
287 287
#endif
0 comments (0 inline)