1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2009
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_CONNECTIVITY_H
20 #define LEMON_CONNECTIVITY_H
22 #include <lemon/dfs.h>
23 #include <lemon/bfs.h>
24 #include <lemon/core.h>
25 #include <lemon/maps.h>
26 #include <lemon/adaptors.h>
28 #include <lemon/concepts/digraph.h>
29 #include <lemon/concepts/graph.h>
30 #include <lemon/concept_check.h>
35 /// \ingroup graph_properties
37 /// \brief Connectivity algorithms
39 /// Connectivity algorithms
43 /// \ingroup graph_properties
45 /// \brief Check whether an undirected graph is connected.
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.
50 /// \return \c true if the graph is connected.
51 /// \note By definition, the empty graph is connected.
53 /// \see countConnectedComponents(), connectedComponents()
54 /// \see stronglyConnected()
55 template <typename Graph>
56 bool connected(const Graph& graph) {
57 checkConcept<concepts::Graph, Graph>();
58 typedef typename Graph::NodeIt NodeIt;
59 if (NodeIt(graph) == INVALID) return true;
60 Dfs<Graph> dfs(graph);
61 dfs.run(NodeIt(graph));
62 for (NodeIt it(graph); it != INVALID; ++it) {
63 if (!dfs.reached(it)) {
70 /// \ingroup graph_properties
72 /// \brief Count the number of connected components of an undirected graph
74 /// This function counts the number of connected components of the given
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.
81 /// \return The number of connected components.
82 /// \note By definition, the empty graph consists
83 /// of zero connected components.
85 /// \see connected(), connectedComponents()
86 template <typename Graph>
87 int countConnectedComponents(const Graph &graph) {
88 checkConcept<concepts::Graph, Graph>();
89 typedef typename Graph::Node Node;
90 typedef typename Graph::Arc Arc;
92 typedef NullMap<Node, Arc> PredMap;
93 typedef NullMap<Node, int> DistMap;
97 template SetPredMap<PredMap>::
98 template SetDistMap<DistMap>::
102 bfs.predMap(predMap);
105 bfs.distMap(distMap);
108 for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
109 if (!bfs.reached(n)) {
118 /// \ingroup graph_properties
120 /// \brief Find the connected components of an undirected graph
122 /// This function finds the connected components of the given undirected
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.
129 /// \image html connected_components.png
130 /// \image latex connected_components.eps "Connected components" width=\textwidth
132 /// \param graph The undirected graph.
133 /// \retval compMap A writable node map. The values will be set from 0 to
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
136 /// set continuously.
137 /// \return The number of connected components.
138 /// \note By definition, the empty graph consists
139 /// of zero connected components.
141 /// \see connected(), countConnectedComponents()
142 template <class Graph, class NodeMap>
143 int connectedComponents(const Graph &graph, NodeMap &compMap) {
144 checkConcept<concepts::Graph, Graph>();
145 typedef typename Graph::Node Node;
146 typedef typename Graph::Arc Arc;
147 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
149 typedef NullMap<Node, Arc> PredMap;
150 typedef NullMap<Node, int> DistMap;
153 typename Bfs<Graph>::
154 template SetPredMap<PredMap>::
155 template SetDistMap<DistMap>::
159 bfs.predMap(predMap);
162 bfs.distMap(distMap);
165 for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
166 if(!bfs.reached(n)) {
168 while (!bfs.emptyQueue()) {
169 compMap.set(bfs.nextNode(), compNum);
170 bfs.processNextNode();
178 namespace _connectivity_bits {
180 template <typename Digraph, typename Iterator >
181 struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
183 typedef typename Digraph::Node Node;
184 LeaveOrderVisitor(Iterator it) : _it(it) {}
186 void leave(const Node& node) {
194 template <typename Digraph, typename Map>
195 struct FillMapVisitor : public DfsVisitor<Digraph> {
197 typedef typename Digraph::Node Node;
198 typedef typename Map::Value Value;
200 FillMapVisitor(Map& map, Value& value)
201 : _map(map), _value(value) {}
203 void reach(const Node& node) {
204 _map.set(node, _value);
211 template <typename Digraph, typename ArcMap>
212 struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
214 typedef typename Digraph::Node Node;
215 typedef typename Digraph::Arc Arc;
217 StronglyConnectedCutArcsVisitor(const Digraph& digraph,
220 : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
221 _compMap(digraph, -1), _num(-1) {
224 void start(const Node&) {
228 void reach(const Node& node) {
229 _compMap.set(node, _num);
232 void examine(const Arc& arc) {
233 if (_compMap[_digraph.source(arc)] !=
234 _compMap[_digraph.target(arc)]) {
235 _cutMap.set(arc, true);
240 const Digraph& _digraph;
244 typename Digraph::template NodeMap<int> _compMap;
251 /// \ingroup graph_properties
253 /// \brief Check whether a directed graph is strongly connected.
255 /// This function checks whether the given directed graph is strongly
256 /// connected, i.e. any two nodes of the digraph are
257 /// connected with directed paths in both direction.
259 /// \return \c true if the digraph is strongly connected.
260 /// \note By definition, the empty digraph is strongly connected.
262 /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
264 template <typename Digraph>
265 bool stronglyConnected(const Digraph& digraph) {
266 checkConcept<concepts::Digraph, Digraph>();
268 typedef typename Digraph::Node Node;
269 typedef typename Digraph::NodeIt NodeIt;
271 typename Digraph::Node source = NodeIt(digraph);
272 if (source == INVALID) return true;
274 using namespace _connectivity_bits;
276 typedef DfsVisitor<Digraph> Visitor;
279 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
281 dfs.addSource(source);
284 for (NodeIt it(digraph); it != INVALID; ++it) {
285 if (!dfs.reached(it)) {
290 typedef ReverseDigraph<const Digraph> RDigraph;
291 typedef typename RDigraph::NodeIt RNodeIt;
292 RDigraph rdigraph(digraph);
294 typedef DfsVisitor<RDigraph> RVisitor;
297 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
299 rdfs.addSource(source);
302 for (RNodeIt it(rdigraph); it != INVALID; ++it) {
303 if (!rdfs.reached(it)) {
311 /// \ingroup graph_properties
313 /// \brief Count the number of strongly connected components of a
316 /// This function counts the number of strongly connected components of
317 /// the given directed graph.
319 /// The strongly connected components are the classes of an
320 /// equivalence relation on the nodes of a digraph. Two nodes are in
321 /// the same class if they are connected with directed paths in both
324 /// \return The number of strongly connected components.
325 /// \note By definition, the empty digraph has zero
326 /// strongly connected components.
328 /// \see stronglyConnected(), stronglyConnectedComponents()
329 template <typename Digraph>
330 int countStronglyConnectedComponents(const Digraph& digraph) {
331 checkConcept<concepts::Digraph, Digraph>();
333 using namespace _connectivity_bits;
335 typedef typename Digraph::Node Node;
336 typedef typename Digraph::Arc Arc;
337 typedef typename Digraph::NodeIt NodeIt;
338 typedef typename Digraph::ArcIt ArcIt;
340 typedef std::vector<Node> Container;
341 typedef typename Container::iterator Iterator;
343 Container nodes(countNodes(digraph));
344 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
345 Visitor visitor(nodes.begin());
347 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
349 for (NodeIt it(digraph); it != INVALID; ++it) {
350 if (!dfs.reached(it)) {
356 typedef typename Container::reverse_iterator RIterator;
357 typedef ReverseDigraph<const Digraph> RDigraph;
359 RDigraph rdigraph(digraph);
361 typedef DfsVisitor<Digraph> RVisitor;
364 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
369 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
370 if (!rdfs.reached(*it)) {
379 /// \ingroup graph_properties
381 /// \brief Find the strongly connected components of a directed graph
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).
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
393 /// \image html strongly_connected_components.png
394 /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
396 /// \param digraph The digraph.
397 /// \retval compMap A writable node map. The values will be set from 0 to
398 /// the number of the strongly connected components minus one. Each value
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.
405 /// \see stronglyConnected(), countStronglyConnectedComponents()
406 template <typename Digraph, typename NodeMap>
407 int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
408 checkConcept<concepts::Digraph, Digraph>();
409 typedef typename Digraph::Node Node;
410 typedef typename Digraph::NodeIt NodeIt;
411 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
413 using namespace _connectivity_bits;
415 typedef std::vector<Node> Container;
416 typedef typename Container::iterator Iterator;
418 Container nodes(countNodes(digraph));
419 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
420 Visitor visitor(nodes.begin());
422 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
424 for (NodeIt it(digraph); it != INVALID; ++it) {
425 if (!dfs.reached(it)) {
431 typedef typename Container::reverse_iterator RIterator;
432 typedef ReverseDigraph<const Digraph> RDigraph;
434 RDigraph rdigraph(digraph);
438 typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
439 RVisitor rvisitor(compMap, compNum);
441 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
444 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
445 if (!rdfs.reached(*it)) {
454 /// \ingroup graph_properties
456 /// \brief Find the cut arcs of the strongly connected components.
458 /// This function finds the cut arcs of the strongly connected components
459 /// of the given digraph.
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
465 /// The strongly connected components are separated by the cut arcs.
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.
473 /// \see stronglyConnected(), stronglyConnectedComponents()
474 template <typename Digraph, typename ArcMap>
475 int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
476 checkConcept<concepts::Digraph, Digraph>();
477 typedef typename Digraph::Node Node;
478 typedef typename Digraph::Arc Arc;
479 typedef typename Digraph::NodeIt NodeIt;
480 checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
482 using namespace _connectivity_bits;
484 typedef std::vector<Node> Container;
485 typedef typename Container::iterator Iterator;
487 Container nodes(countNodes(digraph));
488 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
489 Visitor visitor(nodes.begin());
491 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
493 for (NodeIt it(digraph); it != INVALID; ++it) {
494 if (!dfs.reached(it)) {
500 typedef typename Container::reverse_iterator RIterator;
501 typedef ReverseDigraph<const Digraph> RDigraph;
503 RDigraph rdigraph(digraph);
507 typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
508 RVisitor rvisitor(rdigraph, cutMap, cutNum);
510 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
513 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
514 if (!rdfs.reached(*it)) {
522 namespace _connectivity_bits {
524 template <typename Digraph>
525 class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
527 typedef typename Digraph::Node Node;
528 typedef typename Digraph::Arc Arc;
529 typedef typename Digraph::Edge Edge;
531 CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
532 : _graph(graph), _compNum(compNum),
533 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
535 void start(const Node& node) {
536 _predMap.set(node, INVALID);
539 void reach(const Node& node) {
540 _numMap.set(node, _num);
541 _retMap.set(node, _num);
545 void discover(const Arc& edge) {
546 _predMap.set(_graph.target(edge), _graph.source(edge));
549 void examine(const Arc& edge) {
550 if (_graph.source(edge) == _graph.target(edge) &&
551 _graph.direction(edge)) {
555 if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
558 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
559 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
563 void backtrack(const Arc& edge) {
564 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
565 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
567 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
573 const Digraph& _graph;
576 typename Digraph::template NodeMap<int> _numMap;
577 typename Digraph::template NodeMap<int> _retMap;
578 typename Digraph::template NodeMap<Node> _predMap;
582 template <typename Digraph, typename ArcMap>
583 class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
585 typedef typename Digraph::Node Node;
586 typedef typename Digraph::Arc Arc;
587 typedef typename Digraph::Edge Edge;
589 BiNodeConnectedComponentsVisitor(const Digraph& graph,
590 ArcMap& compMap, int &compNum)
591 : _graph(graph), _compMap(compMap), _compNum(compNum),
592 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
594 void start(const Node& node) {
595 _predMap.set(node, INVALID);
598 void reach(const Node& node) {
599 _numMap.set(node, _num);
600 _retMap.set(node, _num);
604 void discover(const Arc& edge) {
605 Node target = _graph.target(edge);
606 _predMap.set(target, edge);
607 _edgeStack.push(edge);
610 void examine(const Arc& edge) {
611 Node source = _graph.source(edge);
612 Node target = _graph.target(edge);
613 if (source == target && _graph.direction(edge)) {
614 _compMap.set(edge, _compNum);
618 if (_numMap[target] < _numMap[source]) {
619 if (_predMap[source] != _graph.oppositeArc(edge)) {
620 _edgeStack.push(edge);
623 if (_predMap[source] != INVALID &&
624 target == _graph.source(_predMap[source])) {
627 if (_retMap[source] > _numMap[target]) {
628 _retMap.set(source, _numMap[target]);
632 void backtrack(const Arc& edge) {
633 Node source = _graph.source(edge);
634 Node target = _graph.target(edge);
635 if (_retMap[source] > _retMap[target]) {
636 _retMap.set(source, _retMap[target]);
638 if (_numMap[source] <= _retMap[target]) {
639 while (_edgeStack.top() != edge) {
640 _compMap.set(_edgeStack.top(), _compNum);
643 _compMap.set(edge, _compNum);
650 const Digraph& _graph;
654 typename Digraph::template NodeMap<int> _numMap;
655 typename Digraph::template NodeMap<int> _retMap;
656 typename Digraph::template NodeMap<Arc> _predMap;
657 std::stack<Edge> _edgeStack;
662 template <typename Digraph, typename NodeMap>
663 class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
665 typedef typename Digraph::Node Node;
666 typedef typename Digraph::Arc Arc;
667 typedef typename Digraph::Edge Edge;
669 BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
671 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
672 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
674 void start(const Node& node) {
675 _predMap.set(node, INVALID);
679 void reach(const Node& node) {
680 _numMap.set(node, _num);
681 _retMap.set(node, _num);
685 void discover(const Arc& edge) {
686 _predMap.set(_graph.target(edge), _graph.source(edge));
689 void examine(const Arc& edge) {
690 if (_graph.source(edge) == _graph.target(edge) &&
691 _graph.direction(edge)) {
692 if (!_cutMap[_graph.source(edge)]) {
693 _cutMap.set(_graph.source(edge), true);
698 if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
699 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
700 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
704 void backtrack(const Arc& edge) {
705 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
706 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
708 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
709 if (_predMap[_graph.source(edge)] != INVALID) {
710 if (!_cutMap[_graph.source(edge)]) {
711 _cutMap.set(_graph.source(edge), true);
714 } else if (rootCut) {
715 if (!_cutMap[_graph.source(edge)]) {
716 _cutMap.set(_graph.source(edge), true);
726 const Digraph& _graph;
730 typename Digraph::template NodeMap<int> _numMap;
731 typename Digraph::template NodeMap<int> _retMap;
732 typename Digraph::template NodeMap<Node> _predMap;
733 std::stack<Edge> _edgeStack;
740 template <typename Graph>
741 int countBiNodeConnectedComponents(const Graph& graph);
743 /// \ingroup graph_properties
745 /// \brief Check whether an undirected graph is bi-node-connected.
747 /// This function checks whether the given undirected graph is
748 /// bi-node-connected, i.e. a connected graph without articulation
751 /// \return \c true if the graph bi-node-connected.
753 /// \note By definition,
754 /// \li a graph consisting of zero or one node is bi-node-connected,
755 /// \li a graph consisting of two isolated nodes
756 /// is \e not bi-node-connected and
757 /// \li a graph consisting of two nodes connected by an edge
758 /// is bi-node-connected.
760 /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
761 template <typename Graph>
762 bool biNodeConnected(const Graph& graph) {
763 bool hasNonIsolated = false, hasIsolated = false;
764 for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
765 if (typename Graph::OutArcIt(graph, n) == INVALID) {
766 if (hasIsolated || hasNonIsolated) {
775 hasNonIsolated = true;
779 return countBiNodeConnectedComponents(graph) <= 1;
782 /// \ingroup graph_properties
784 /// \brief Count the number of bi-node-connected components of an
785 /// undirected graph.
787 /// This function counts the number of bi-node-connected components of
788 /// the given undirected graph.
790 /// The bi-node-connected components are the classes of an equivalence
791 /// relation on the edges of a undirected graph. Two edges are in the
792 /// same class if they are on same circle.
794 /// \return The number of bi-node-connected components.
796 /// \see biNodeConnected(), biNodeConnectedComponents()
797 template <typename Graph>
798 int countBiNodeConnectedComponents(const Graph& graph) {
799 checkConcept<concepts::Graph, Graph>();
800 typedef typename Graph::NodeIt NodeIt;
802 using namespace _connectivity_bits;
804 typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
807 Visitor visitor(graph, compNum);
809 DfsVisit<Graph, Visitor> dfs(graph, visitor);
812 for (NodeIt it(graph); it != INVALID; ++it) {
813 if (!dfs.reached(it)) {
821 /// \ingroup graph_properties
823 /// \brief Find the bi-node-connected components of an undirected graph.
825 /// This function finds the bi-node-connected components of the given
826 /// undirected graph.
828 /// The bi-node-connected components are the classes of an equivalence
829 /// relation on the edges of a undirected graph. Two edges are in the
830 /// same class if they are on same circle.
832 /// \image html node_biconnected_components.png
833 /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
835 /// \param graph The undirected graph.
836 /// \retval compMap A writable edge map. The values will be set from 0
837 /// to the number of the bi-node-connected components minus one. Each
838 /// value of the map will be set exactly once, and the values of a
839 /// certain component will be set continuously.
840 /// \return The number of bi-node-connected components.
842 /// \see biNodeConnected(), countBiNodeConnectedComponents()
843 template <typename Graph, typename EdgeMap>
844 int biNodeConnectedComponents(const Graph& graph,
846 checkConcept<concepts::Graph, Graph>();
847 typedef typename Graph::NodeIt NodeIt;
848 typedef typename Graph::Edge Edge;
849 checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
851 using namespace _connectivity_bits;
853 typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
856 Visitor visitor(graph, compMap, compNum);
858 DfsVisit<Graph, Visitor> dfs(graph, visitor);
861 for (NodeIt it(graph); it != INVALID; ++it) {
862 if (!dfs.reached(it)) {
870 /// \ingroup graph_properties
872 /// \brief Find the bi-node-connected cut nodes in an undirected graph.
874 /// This function finds the bi-node-connected cut nodes in the given
875 /// undirected graph.
877 /// The bi-node-connected components are the classes of an equivalence
878 /// relation on the edges of a undirected graph. Two edges are in the
879 /// same class if they are on same circle.
880 /// The bi-node-connected components are separted by the cut nodes of
883 /// \param graph The undirected graph.
884 /// \retval cutMap A writable node map. The values will be set to
885 /// \c true for the nodes that separate two or more components
886 /// (exactly once for each cut node), and will not be changed for
888 /// \return The number of the cut nodes.
890 /// \see biNodeConnected(), biNodeConnectedComponents()
891 template <typename Graph, typename NodeMap>
892 int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
893 checkConcept<concepts::Graph, Graph>();
894 typedef typename Graph::Node Node;
895 typedef typename Graph::NodeIt NodeIt;
896 checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
898 using namespace _connectivity_bits;
900 typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
903 Visitor visitor(graph, cutMap, cutNum);
905 DfsVisit<Graph, Visitor> dfs(graph, visitor);
908 for (NodeIt it(graph); it != INVALID; ++it) {
909 if (!dfs.reached(it)) {
917 namespace _connectivity_bits {
919 template <typename Digraph>
920 class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
922 typedef typename Digraph::Node Node;
923 typedef typename Digraph::Arc Arc;
924 typedef typename Digraph::Edge Edge;
926 CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
927 : _graph(graph), _compNum(compNum),
928 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
930 void start(const Node& node) {
931 _predMap.set(node, INVALID);
934 void reach(const Node& node) {
935 _numMap.set(node, _num);
936 _retMap.set(node, _num);
940 void leave(const Node& node) {
941 if (_numMap[node] <= _retMap[node]) {
946 void discover(const Arc& edge) {
947 _predMap.set(_graph.target(edge), edge);
950 void examine(const Arc& edge) {
951 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
954 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
955 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
959 void backtrack(const Arc& edge) {
960 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
961 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
966 const Digraph& _graph;
969 typename Digraph::template NodeMap<int> _numMap;
970 typename Digraph::template NodeMap<int> _retMap;
971 typename Digraph::template NodeMap<Arc> _predMap;
975 template <typename Digraph, typename NodeMap>
976 class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
978 typedef typename Digraph::Node Node;
979 typedef typename Digraph::Arc Arc;
980 typedef typename Digraph::Edge Edge;
982 BiEdgeConnectedComponentsVisitor(const Digraph& graph,
983 NodeMap& compMap, int &compNum)
984 : _graph(graph), _compMap(compMap), _compNum(compNum),
985 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
987 void start(const Node& node) {
988 _predMap.set(node, INVALID);
991 void reach(const Node& node) {
992 _numMap.set(node, _num);
993 _retMap.set(node, _num);
994 _nodeStack.push(node);
998 void leave(const Node& node) {
999 if (_numMap[node] <= _retMap[node]) {
1000 while (_nodeStack.top() != node) {
1001 _compMap.set(_nodeStack.top(), _compNum);
1004 _compMap.set(node, _compNum);
1010 void discover(const Arc& edge) {
1011 _predMap.set(_graph.target(edge), edge);
1014 void examine(const Arc& edge) {
1015 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
1018 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1019 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1023 void backtrack(const Arc& edge) {
1024 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1025 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1030 const Digraph& _graph;
1034 typename Digraph::template NodeMap<int> _numMap;
1035 typename Digraph::template NodeMap<int> _retMap;
1036 typename Digraph::template NodeMap<Arc> _predMap;
1037 std::stack<Node> _nodeStack;
1042 template <typename Digraph, typename ArcMap>
1043 class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
1045 typedef typename Digraph::Node Node;
1046 typedef typename Digraph::Arc Arc;
1047 typedef typename Digraph::Edge Edge;
1049 BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
1050 ArcMap& cutMap, int &cutNum)
1051 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
1052 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
1054 void start(const Node& node) {
1055 _predMap[node] = INVALID;
1058 void reach(const Node& node) {
1059 _numMap.set(node, _num);
1060 _retMap.set(node, _num);
1064 void leave(const Node& node) {
1065 if (_numMap[node] <= _retMap[node]) {
1066 if (_predMap[node] != INVALID) {
1067 _cutMap.set(_predMap[node], true);
1073 void discover(const Arc& edge) {
1074 _predMap.set(_graph.target(edge), edge);
1077 void examine(const Arc& edge) {
1078 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
1081 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1082 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1086 void backtrack(const Arc& edge) {
1087 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1088 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1093 const Digraph& _graph;
1097 typename Digraph::template NodeMap<int> _numMap;
1098 typename Digraph::template NodeMap<int> _retMap;
1099 typename Digraph::template NodeMap<Arc> _predMap;
1104 template <typename Graph>
1105 int countBiEdgeConnectedComponents(const Graph& graph);
1107 /// \ingroup graph_properties
1109 /// \brief Check whether an undirected graph is bi-edge-connected.
1111 /// This function checks whether the given undirected graph is
1112 /// bi-edge-connected, i.e. any two nodes are connected with at least
1113 /// two edge-disjoint paths.
1115 /// \return \c true if the graph is bi-edge-connected.
1116 /// \note By definition, the empty graph is bi-edge-connected.
1118 /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
1119 template <typename Graph>
1120 bool biEdgeConnected(const Graph& graph) {
1121 return countBiEdgeConnectedComponents(graph) <= 1;
1124 /// \ingroup graph_properties
1126 /// \brief Count the number of bi-edge-connected components of an
1127 /// undirected graph.
1129 /// This function counts the number of bi-edge-connected components of
1130 /// the given undirected graph.
1132 /// The bi-edge-connected components are the classes of an equivalence
1133 /// relation on the nodes of an undirected graph. Two nodes are in the
1134 /// same class if they are connected with at least two edge-disjoint
1137 /// \return The number of bi-edge-connected components.
1139 /// \see biEdgeConnected(), biEdgeConnectedComponents()
1140 template <typename Graph>
1141 int countBiEdgeConnectedComponents(const Graph& graph) {
1142 checkConcept<concepts::Graph, Graph>();
1143 typedef typename Graph::NodeIt NodeIt;
1145 using namespace _connectivity_bits;
1147 typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1150 Visitor visitor(graph, compNum);
1152 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1155 for (NodeIt it(graph); it != INVALID; ++it) {
1156 if (!dfs.reached(it)) {
1164 /// \ingroup graph_properties
1166 /// \brief Find the bi-edge-connected components of an undirected graph.
1168 /// This function finds the bi-edge-connected components of the given
1169 /// undirected graph.
1171 /// The bi-edge-connected components are the classes of an equivalence
1172 /// relation on the nodes of an undirected graph. Two nodes are in the
1173 /// same class if they are connected with at least two edge-disjoint
1176 /// \image html edge_biconnected_components.png
1177 /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
1179 /// \param graph The undirected graph.
1180 /// \retval compMap A writable node map. The values will be set from 0 to
1181 /// the number of the bi-edge-connected components minus one. Each value
1182 /// of the map will be set exactly once, and the values of a certain
1183 /// component will be set continuously.
1184 /// \return The number of bi-edge-connected components.
1186 /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
1187 template <typename Graph, typename NodeMap>
1188 int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
1189 checkConcept<concepts::Graph, Graph>();
1190 typedef typename Graph::NodeIt NodeIt;
1191 typedef typename Graph::Node Node;
1192 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1194 using namespace _connectivity_bits;
1196 typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1199 Visitor visitor(graph, compMap, compNum);
1201 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1204 for (NodeIt it(graph); it != INVALID; ++it) {
1205 if (!dfs.reached(it)) {
1213 /// \ingroup graph_properties
1215 /// \brief Find the bi-edge-connected cut edges in an undirected graph.
1217 /// This function finds the bi-edge-connected cut edges in the given
1218 /// undirected graph.
1220 /// The bi-edge-connected components are the classes of an equivalence
1221 /// relation on the nodes of an undirected graph. Two nodes are in the
1222 /// same class if they are connected with at least two edge-disjoint
1224 /// The bi-edge-connected components are separted by the cut edges of
1227 /// \param graph The undirected graph.
1228 /// \retval cutMap A writable edge map. The values will be set to \c true
1229 /// for the cut edges (exactly once for each cut edge), and will not be
1230 /// changed for other edges.
1231 /// \return The number of cut edges.
1233 /// \see biEdgeConnected(), biEdgeConnectedComponents()
1234 template <typename Graph, typename EdgeMap>
1235 int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
1236 checkConcept<concepts::Graph, Graph>();
1237 typedef typename Graph::NodeIt NodeIt;
1238 typedef typename Graph::Edge Edge;
1239 checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
1241 using namespace _connectivity_bits;
1243 typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1246 Visitor visitor(graph, cutMap, cutNum);
1248 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1251 for (NodeIt it(graph); it != INVALID; ++it) {
1252 if (!dfs.reached(it)) {
1261 namespace _connectivity_bits {
1263 template <typename Digraph, typename IntNodeMap>
1264 class TopologicalSortVisitor : public DfsVisitor<Digraph> {
1266 typedef typename Digraph::Node Node;
1267 typedef typename Digraph::Arc edge;
1269 TopologicalSortVisitor(IntNodeMap& order, int num)
1270 : _order(order), _num(num) {}
1272 void leave(const Node& node) {
1273 _order.set(node, --_num);
1283 /// \ingroup graph_properties
1285 /// \brief Check whether a digraph is DAG.
1287 /// This function checks whether the given digraph is DAG, i.e.
1288 /// \e Directed \e Acyclic \e Graph.
1289 /// \return \c true if there is no directed cycle in the digraph.
1291 template <typename Digraph>
1292 bool dag(const Digraph& digraph) {
1294 checkConcept<concepts::Digraph, Digraph>();
1296 typedef typename Digraph::Node Node;
1297 typedef typename Digraph::NodeIt NodeIt;
1298 typedef typename Digraph::Arc Arc;
1300 typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1302 typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1303 Create dfs(digraph);
1305 ProcessedMap processed(digraph);
1306 dfs.processedMap(processed);
1309 for (NodeIt it(digraph); it != INVALID; ++it) {
1310 if (!dfs.reached(it)) {
1312 while (!dfs.emptyQueue()) {
1313 Arc arc = dfs.nextArc();
1314 Node target = digraph.target(arc);
1315 if (dfs.reached(target) && !processed[target]) {
1318 dfs.processNextArc();
1325 /// \ingroup graph_properties
1327 /// \brief Sort the nodes of a DAG into topolgical order.
1329 /// This function sorts the nodes of the given acyclic digraph (DAG)
1330 /// into topolgical order.
1332 /// \param digraph The digraph, which must be DAG.
1333 /// \retval order A writable node map. The values will be set from 0 to
1334 /// the number of the nodes in the digraph minus one. Each value of the
1335 /// map will be set exactly once, and the values will be set descending
1338 /// \see dag(), checkedTopologicalSort()
1339 template <typename Digraph, typename NodeMap>
1340 void topologicalSort(const Digraph& digraph, NodeMap& order) {
1341 using namespace _connectivity_bits;
1343 checkConcept<concepts::Digraph, Digraph>();
1344 checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
1346 typedef typename Digraph::Node Node;
1347 typedef typename Digraph::NodeIt NodeIt;
1348 typedef typename Digraph::Arc Arc;
1350 TopologicalSortVisitor<Digraph, NodeMap>
1351 visitor(order, countNodes(digraph));
1353 DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1354 dfs(digraph, visitor);
1357 for (NodeIt it(digraph); it != INVALID; ++it) {
1358 if (!dfs.reached(it)) {
1365 /// \ingroup graph_properties
1367 /// \brief Sort the nodes of a DAG into topolgical order.
1369 /// This function sorts the nodes of the given acyclic digraph (DAG)
1370 /// into topolgical order and also checks whether the given digraph
1373 /// \param digraph The digraph.
1374 /// \retval order A readable and writable node map. The values will be
1375 /// set from 0 to the number of the nodes in the digraph minus one.
1376 /// Each value of the map will be set exactly once, and the values will
1377 /// be set descending order.
1378 /// \return \c false if the digraph is not DAG.
1380 /// \see dag(), topologicalSort()
1381 template <typename Digraph, typename NodeMap>
1382 bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
1383 using namespace _connectivity_bits;
1385 checkConcept<concepts::Digraph, Digraph>();
1386 checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
1389 typedef typename Digraph::Node Node;
1390 typedef typename Digraph::NodeIt NodeIt;
1391 typedef typename Digraph::Arc Arc;
1393 for (NodeIt it(digraph); it != INVALID; ++it) {
1397 TopologicalSortVisitor<Digraph, NodeMap>
1398 visitor(order, countNodes(digraph));
1400 DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1401 dfs(digraph, visitor);
1404 for (NodeIt it(digraph); it != INVALID; ++it) {
1405 if (!dfs.reached(it)) {
1407 while (!dfs.emptyQueue()) {
1408 Arc arc = dfs.nextArc();
1409 Node target = digraph.target(arc);
1410 if (dfs.reached(target) && order[target] == -1) {
1413 dfs.processNextArc();
1420 /// \ingroup graph_properties
1422 /// \brief Check whether an undirected graph is acyclic.
1424 /// This function checks whether the given undirected graph is acyclic.
1425 /// \return \c true if there is no cycle in the graph.
1427 template <typename Graph>
1428 bool acyclic(const Graph& graph) {
1429 checkConcept<concepts::Graph, Graph>();
1430 typedef typename Graph::Node Node;
1431 typedef typename Graph::NodeIt NodeIt;
1432 typedef typename Graph::Arc Arc;
1433 Dfs<Graph> dfs(graph);
1435 for (NodeIt it(graph); it != INVALID; ++it) {
1436 if (!dfs.reached(it)) {
1438 while (!dfs.emptyQueue()) {
1439 Arc arc = dfs.nextArc();
1440 Node source = graph.source(arc);
1441 Node target = graph.target(arc);
1442 if (dfs.reached(target) &&
1443 dfs.predArc(source) != graph.oppositeArc(arc)) {
1446 dfs.processNextArc();
1453 /// \ingroup graph_properties
1455 /// \brief Check whether an undirected graph is tree.
1457 /// This function checks whether the given undirected graph is tree.
1458 /// \return \c true if the graph is acyclic and connected.
1459 /// \see acyclic(), connected()
1460 template <typename Graph>
1461 bool tree(const Graph& graph) {
1462 checkConcept<concepts::Graph, Graph>();
1463 typedef typename Graph::Node Node;
1464 typedef typename Graph::NodeIt NodeIt;
1465 typedef typename Graph::Arc Arc;
1466 if (NodeIt(graph) == INVALID) return true;
1467 Dfs<Graph> dfs(graph);
1469 dfs.addSource(NodeIt(graph));
1470 while (!dfs.emptyQueue()) {
1471 Arc arc = dfs.nextArc();
1472 Node source = graph.source(arc);
1473 Node target = graph.target(arc);
1474 if (dfs.reached(target) &&
1475 dfs.predArc(source) != graph.oppositeArc(arc)) {
1478 dfs.processNextArc();
1480 for (NodeIt it(graph); it != INVALID; ++it) {
1481 if (!dfs.reached(it)) {
1488 namespace _connectivity_bits {
1490 template <typename Digraph>
1491 class BipartiteVisitor : public BfsVisitor<Digraph> {
1493 typedef typename Digraph::Arc Arc;
1494 typedef typename Digraph::Node Node;
1496 BipartiteVisitor(const Digraph& graph, bool& bipartite)
1497 : _graph(graph), _part(graph), _bipartite(bipartite) {}
1499 void start(const Node& node) {
1502 void discover(const Arc& edge) {
1503 _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1505 void examine(const Arc& edge) {
1506 _bipartite = _bipartite &&
1507 _part[_graph.target(edge)] != _part[_graph.source(edge)];
1512 const Digraph& _graph;
1513 typename Digraph::template NodeMap<bool> _part;
1517 template <typename Digraph, typename PartMap>
1518 class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
1520 typedef typename Digraph::Arc Arc;
1521 typedef typename Digraph::Node Node;
1523 BipartitePartitionsVisitor(const Digraph& graph,
1524 PartMap& part, bool& bipartite)
1525 : _graph(graph), _part(part), _bipartite(bipartite) {}
1527 void start(const Node& node) {
1528 _part.set(node, true);
1530 void discover(const Arc& edge) {
1531 _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1533 void examine(const Arc& edge) {
1534 _bipartite = _bipartite &&
1535 _part[_graph.target(edge)] != _part[_graph.source(edge)];
1540 const Digraph& _graph;
1546 /// \ingroup graph_properties
1548 /// \brief Check whether an undirected graph is bipartite.
1550 /// The function checks whether the given undirected graph is bipartite.
1551 /// \return \c true if the graph is bipartite.
1553 /// \see bipartitePartitions()
1554 template<typename Graph>
1555 bool bipartite(const Graph &graph){
1556 using namespace _connectivity_bits;
1558 checkConcept<concepts::Graph, Graph>();
1560 typedef typename Graph::NodeIt NodeIt;
1561 typedef typename Graph::ArcIt ArcIt;
1563 bool bipartite = true;
1565 BipartiteVisitor<Graph>
1566 visitor(graph, bipartite);
1567 BfsVisit<Graph, BipartiteVisitor<Graph> >
1568 bfs(graph, visitor);
1570 for(NodeIt it(graph); it != INVALID; ++it) {
1571 if(!bfs.reached(it)){
1573 while (!bfs.emptyQueue()) {
1574 bfs.processNextNode();
1575 if (!bipartite) return false;
1582 /// \ingroup graph_properties
1584 /// \brief Find the bipartite partitions of an undirected graph.
1586 /// This function checks whether the given undirected graph is bipartite
1587 /// and gives back the bipartite partitions.
1589 /// \image html bipartite_partitions.png
1590 /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
1592 /// \param graph The undirected graph.
1593 /// \retval partMap A writable node map of \c bool (or convertible) value
1594 /// type. The values will be set to \c true for one component and
1595 /// \c false for the other one.
1596 /// \return \c true if the graph is bipartite, \c false otherwise.
1598 /// \see bipartite()
1599 template<typename Graph, typename NodeMap>
1600 bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
1601 using namespace _connectivity_bits;
1603 checkConcept<concepts::Graph, Graph>();
1604 checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
1606 typedef typename Graph::Node Node;
1607 typedef typename Graph::NodeIt NodeIt;
1608 typedef typename Graph::ArcIt ArcIt;
1610 bool bipartite = true;
1612 BipartitePartitionsVisitor<Graph, NodeMap>
1613 visitor(graph, partMap, bipartite);
1614 BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
1615 bfs(graph, visitor);
1617 for(NodeIt it(graph); it != INVALID; ++it) {
1618 if(!bfs.reached(it)){
1620 while (!bfs.emptyQueue()) {
1621 bfs.processNextNode();
1622 if (!bipartite) return false;
1629 /// \ingroup graph_properties
1631 /// \brief Check whether the given graph contains no loop arcs/edges.
1633 /// This function returns \c true if there are no loop arcs/edges in
1634 /// the given graph. It works for both directed and undirected graphs.
1635 template <typename Graph>
1636 bool loopFree(const Graph& graph) {
1637 for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
1638 if (graph.source(it) == graph.target(it)) return false;
1643 /// \ingroup graph_properties
1645 /// \brief Check whether the given graph contains no parallel arcs/edges.
1647 /// This function returns \c true if there are no parallel arcs/edges in
1648 /// the given graph. It works for both directed and undirected graphs.
1649 template <typename Graph>
1650 bool parallelFree(const Graph& graph) {
1651 typename Graph::template NodeMap<int> reached(graph, 0);
1653 for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1654 for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
1655 if (reached[graph.target(a)] == cnt) return false;
1656 reached[graph.target(a)] = cnt;
1663 /// \ingroup graph_properties
1665 /// \brief Check whether the given graph is simple.
1667 /// This function returns \c true if the given graph is simple, i.e.
1668 /// it contains no loop arcs/edges and no parallel arcs/edges.
1669 /// The function works for both directed and undirected graphs.
1670 /// \see loopFree(), parallelFree()
1671 template <typename Graph>
1672 bool simpleGraph(const Graph& graph) {
1673 typename Graph::template NodeMap<int> reached(graph, 0);
1675 for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1677 for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
1678 if (reached[graph.target(a)] == cnt) return false;
1679 reached[graph.target(a)] = cnt;
1688 #endif //LEMON_CONNECTIVITY_H