1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2008
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 connectivity
37 /// \brief Connectivity algorithms
39 /// Connectivity algorithms
43 /// \ingroup connectivity
45 /// \brief Check whether the given undirected graph is connected.
47 /// Check whether the given undirected graph is connected.
48 /// \param graph The undirected graph.
49 /// \return %True when there is path between any two nodes in the graph.
50 /// \note By definition, the empty graph is connected.
51 template <typename Graph>
52 bool connected(const Graph& graph) {
53 checkConcept<concepts::Graph, Graph>();
54 typedef typename Graph::NodeIt NodeIt;
55 if (NodeIt(graph) == INVALID) return true;
56 Dfs<Graph> dfs(graph);
57 dfs.run(NodeIt(graph));
58 for (NodeIt it(graph); it != INVALID; ++it) {
59 if (!dfs.reached(it)) {
66 /// \ingroup connectivity
68 /// \brief Count the number of connected components of an undirected graph
70 /// Count the number of connected components of an undirected graph
72 /// \param graph The graph. It must be undirected.
73 /// \return The number of components
74 /// \note By definition, the empty graph consists
75 /// of zero connected components.
76 template <typename Graph>
77 int countConnectedComponents(const Graph &graph) {
78 checkConcept<concepts::Graph, Graph>();
79 typedef typename Graph::Node Node;
80 typedef typename Graph::Arc Arc;
82 typedef NullMap<Node, Arc> PredMap;
83 typedef NullMap<Node, int> DistMap;
87 template SetPredMap<PredMap>::
88 template SetDistMap<DistMap>::
98 for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
99 if (!bfs.reached(n)) {
108 /// \ingroup connectivity
110 /// \brief Find the connected components of an undirected graph
112 /// Find the connected components of an undirected graph.
114 /// \param graph The graph. It must be undirected.
115 /// \retval compMap A writable node map. The values will be set from 0 to
116 /// the number of the connected components minus one. Each values of the map
117 /// will be set exactly once, the values of a certain component will be
118 /// set continuously.
119 /// \return The number of components
121 template <class Graph, class NodeMap>
122 int connectedComponents(const Graph &graph, NodeMap &compMap) {
123 checkConcept<concepts::Graph, Graph>();
124 typedef typename Graph::Node Node;
125 typedef typename Graph::Arc Arc;
126 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
128 typedef NullMap<Node, Arc> PredMap;
129 typedef NullMap<Node, int> DistMap;
132 typename Bfs<Graph>::
133 template SetPredMap<PredMap>::
134 template SetDistMap<DistMap>::
138 bfs.predMap(predMap);
141 bfs.distMap(distMap);
144 for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
145 if(!bfs.reached(n)) {
147 while (!bfs.emptyQueue()) {
148 compMap.set(bfs.nextNode(), compNum);
149 bfs.processNextNode();
157 namespace _connectivity_bits {
159 template <typename Digraph, typename Iterator >
160 struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
162 typedef typename Digraph::Node Node;
163 LeaveOrderVisitor(Iterator it) : _it(it) {}
165 void leave(const Node& node) {
173 template <typename Digraph, typename Map>
174 struct FillMapVisitor : public DfsVisitor<Digraph> {
176 typedef typename Digraph::Node Node;
177 typedef typename Map::Value Value;
179 FillMapVisitor(Map& map, Value& value)
180 : _map(map), _value(value) {}
182 void reach(const Node& node) {
183 _map.set(node, _value);
190 template <typename Digraph, typename ArcMap>
191 struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
193 typedef typename Digraph::Node Node;
194 typedef typename Digraph::Arc Arc;
196 StronglyConnectedCutArcsVisitor(const Digraph& digraph,
199 : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
200 _compMap(digraph, -1), _num(-1) {
203 void start(const Node&) {
207 void reach(const Node& node) {
208 _compMap.set(node, _num);
211 void examine(const Arc& arc) {
212 if (_compMap[_digraph.source(arc)] !=
213 _compMap[_digraph.target(arc)]) {
214 _cutMap.set(arc, true);
219 const Digraph& _digraph;
223 typename Digraph::template NodeMap<int> _compMap;
230 /// \ingroup connectivity
232 /// \brief Check whether the given directed graph is strongly connected.
234 /// Check whether the given directed graph is strongly connected. The
235 /// graph is strongly connected when any two nodes of the graph are
236 /// connected with directed paths in both direction.
237 /// \return %False when the graph is not strongly connected.
240 /// \note By definition, the empty graph is strongly connected.
241 template <typename Digraph>
242 bool stronglyConnected(const Digraph& digraph) {
243 checkConcept<concepts::Digraph, Digraph>();
245 typedef typename Digraph::Node Node;
246 typedef typename Digraph::NodeIt NodeIt;
248 typename Digraph::Node source = NodeIt(digraph);
249 if (source == INVALID) return true;
251 using namespace _connectivity_bits;
253 typedef DfsVisitor<Digraph> Visitor;
256 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
258 dfs.addSource(source);
261 for (NodeIt it(digraph); it != INVALID; ++it) {
262 if (!dfs.reached(it)) {
267 typedef ReverseDigraph<const Digraph> RDigraph;
268 typedef typename RDigraph::NodeIt RNodeIt;
269 RDigraph rdigraph(digraph);
271 typedef DfsVisitor<Digraph> RVisitor;
274 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
276 rdfs.addSource(source);
279 for (RNodeIt it(rdigraph); it != INVALID; ++it) {
280 if (!rdfs.reached(it)) {
288 /// \ingroup connectivity
290 /// \brief Count the strongly connected components of a directed graph
292 /// Count the strongly connected components of a directed graph.
293 /// The strongly connected components are the classes of an
294 /// equivalence relation on the nodes of the graph. Two nodes are in
295 /// the same class if they are connected with directed paths in both
298 /// \param digraph The graph.
299 /// \return The number of components
300 /// \note By definition, the empty graph has zero
301 /// strongly connected components.
302 template <typename Digraph>
303 int countStronglyConnectedComponents(const Digraph& digraph) {
304 checkConcept<concepts::Digraph, Digraph>();
306 using namespace _connectivity_bits;
308 typedef typename Digraph::Node Node;
309 typedef typename Digraph::Arc Arc;
310 typedef typename Digraph::NodeIt NodeIt;
311 typedef typename Digraph::ArcIt ArcIt;
313 typedef std::vector<Node> Container;
314 typedef typename Container::iterator Iterator;
316 Container nodes(countNodes(digraph));
317 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
318 Visitor visitor(nodes.begin());
320 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
322 for (NodeIt it(digraph); it != INVALID; ++it) {
323 if (!dfs.reached(it)) {
329 typedef typename Container::reverse_iterator RIterator;
330 typedef ReverseDigraph<const Digraph> RDigraph;
332 RDigraph rdigraph(digraph);
334 typedef DfsVisitor<Digraph> RVisitor;
337 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
342 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
343 if (!rdfs.reached(*it)) {
352 /// \ingroup connectivity
354 /// \brief Find the strongly connected components of a directed graph
356 /// Find the strongly connected components of a directed graph. The
357 /// strongly connected components are the classes of an equivalence
358 /// relation on the nodes of the graph. Two nodes are in
359 /// relationship when there are directed paths between them in both
360 /// direction. In addition, the numbering of components will satisfy
361 /// that there is no arc going from a higher numbered component to
364 /// \param digraph The digraph.
365 /// \retval compMap A writable node map. The values will be set from 0 to
366 /// the number of the strongly connected components minus one. Each value
367 /// of the map will be set exactly once, the values of a certain component
368 /// will be set continuously.
369 /// \return The number of components
371 template <typename Digraph, typename NodeMap>
372 int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
373 checkConcept<concepts::Digraph, Digraph>();
374 typedef typename Digraph::Node Node;
375 typedef typename Digraph::NodeIt NodeIt;
376 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
378 using namespace _connectivity_bits;
380 typedef std::vector<Node> Container;
381 typedef typename Container::iterator Iterator;
383 Container nodes(countNodes(digraph));
384 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
385 Visitor visitor(nodes.begin());
387 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
389 for (NodeIt it(digraph); it != INVALID; ++it) {
390 if (!dfs.reached(it)) {
396 typedef typename Container::reverse_iterator RIterator;
397 typedef ReverseDigraph<const Digraph> RDigraph;
399 RDigraph rdigraph(digraph);
403 typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
404 RVisitor rvisitor(compMap, compNum);
406 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
409 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
410 if (!rdfs.reached(*it)) {
419 /// \ingroup connectivity
421 /// \brief Find the cut arcs of the strongly connected components.
423 /// Find the cut arcs of the strongly connected components.
424 /// The strongly connected components are the classes of an equivalence
425 /// relation on the nodes of the graph. Two nodes are in relationship
426 /// when there are directed paths between them in both direction.
427 /// The strongly connected components are separated by the cut arcs.
429 /// \param graph The graph.
430 /// \retval cutMap A writable node map. The values will be set true when the
431 /// arc is a cut arc.
433 /// \return The number of cut arcs
434 template <typename Digraph, typename ArcMap>
435 int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
436 checkConcept<concepts::Digraph, Digraph>();
437 typedef typename Digraph::Node Node;
438 typedef typename Digraph::Arc Arc;
439 typedef typename Digraph::NodeIt NodeIt;
440 checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
442 using namespace _connectivity_bits;
444 typedef std::vector<Node> Container;
445 typedef typename Container::iterator Iterator;
447 Container nodes(countNodes(graph));
448 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
449 Visitor visitor(nodes.begin());
451 DfsVisit<Digraph, Visitor> dfs(graph, visitor);
453 for (NodeIt it(graph); it != INVALID; ++it) {
454 if (!dfs.reached(it)) {
460 typedef typename Container::reverse_iterator RIterator;
461 typedef ReverseDigraph<const Digraph> RDigraph;
463 RDigraph rgraph(graph);
467 typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
468 RVisitor rvisitor(rgraph, cutMap, cutNum);
470 DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
473 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
474 if (!rdfs.reached(*it)) {
482 namespace _connectivity_bits {
484 template <typename Digraph>
485 class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
487 typedef typename Digraph::Node Node;
488 typedef typename Digraph::Arc Arc;
489 typedef typename Digraph::Edge Edge;
491 CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
492 : _graph(graph), _compNum(compNum),
493 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
495 void start(const Node& node) {
496 _predMap.set(node, INVALID);
499 void reach(const Node& node) {
500 _numMap.set(node, _num);
501 _retMap.set(node, _num);
505 void discover(const Arc& edge) {
506 _predMap.set(_graph.target(edge), _graph.source(edge));
509 void examine(const Arc& edge) {
510 if (_graph.source(edge) == _graph.target(edge) &&
511 _graph.direction(edge)) {
515 if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
518 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
519 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
523 void backtrack(const Arc& edge) {
524 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
525 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
527 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
533 const Digraph& _graph;
536 typename Digraph::template NodeMap<int> _numMap;
537 typename Digraph::template NodeMap<int> _retMap;
538 typename Digraph::template NodeMap<Node> _predMap;
542 template <typename Digraph, typename ArcMap>
543 class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
545 typedef typename Digraph::Node Node;
546 typedef typename Digraph::Arc Arc;
547 typedef typename Digraph::Edge Edge;
549 BiNodeConnectedComponentsVisitor(const Digraph& graph,
550 ArcMap& compMap, int &compNum)
551 : _graph(graph), _compMap(compMap), _compNum(compNum),
552 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
554 void start(const Node& node) {
555 _predMap.set(node, INVALID);
558 void reach(const Node& node) {
559 _numMap.set(node, _num);
560 _retMap.set(node, _num);
564 void discover(const Arc& edge) {
565 Node target = _graph.target(edge);
566 _predMap.set(target, edge);
567 _edgeStack.push(edge);
570 void examine(const Arc& edge) {
571 Node source = _graph.source(edge);
572 Node target = _graph.target(edge);
573 if (source == target && _graph.direction(edge)) {
574 _compMap.set(edge, _compNum);
578 if (_numMap[target] < _numMap[source]) {
579 if (_predMap[source] != _graph.oppositeArc(edge)) {
580 _edgeStack.push(edge);
583 if (_predMap[source] != INVALID &&
584 target == _graph.source(_predMap[source])) {
587 if (_retMap[source] > _numMap[target]) {
588 _retMap.set(source, _numMap[target]);
592 void backtrack(const Arc& edge) {
593 Node source = _graph.source(edge);
594 Node target = _graph.target(edge);
595 if (_retMap[source] > _retMap[target]) {
596 _retMap.set(source, _retMap[target]);
598 if (_numMap[source] <= _retMap[target]) {
599 while (_edgeStack.top() != edge) {
600 _compMap.set(_edgeStack.top(), _compNum);
603 _compMap.set(edge, _compNum);
610 const Digraph& _graph;
614 typename Digraph::template NodeMap<int> _numMap;
615 typename Digraph::template NodeMap<int> _retMap;
616 typename Digraph::template NodeMap<Arc> _predMap;
617 std::stack<Edge> _edgeStack;
622 template <typename Digraph, typename NodeMap>
623 class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
625 typedef typename Digraph::Node Node;
626 typedef typename Digraph::Arc Arc;
627 typedef typename Digraph::Edge Edge;
629 BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
631 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
632 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
634 void start(const Node& node) {
635 _predMap.set(node, INVALID);
639 void reach(const Node& node) {
640 _numMap.set(node, _num);
641 _retMap.set(node, _num);
645 void discover(const Arc& edge) {
646 _predMap.set(_graph.target(edge), _graph.source(edge));
649 void examine(const Arc& edge) {
650 if (_graph.source(edge) == _graph.target(edge) &&
651 _graph.direction(edge)) {
652 if (!_cutMap[_graph.source(edge)]) {
653 _cutMap.set(_graph.source(edge), true);
658 if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
659 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
660 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
664 void backtrack(const Arc& edge) {
665 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
666 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
668 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
669 if (_predMap[_graph.source(edge)] != INVALID) {
670 if (!_cutMap[_graph.source(edge)]) {
671 _cutMap.set(_graph.source(edge), true);
674 } else if (rootCut) {
675 if (!_cutMap[_graph.source(edge)]) {
676 _cutMap.set(_graph.source(edge), true);
686 const Digraph& _graph;
690 typename Digraph::template NodeMap<int> _numMap;
691 typename Digraph::template NodeMap<int> _retMap;
692 typename Digraph::template NodeMap<Node> _predMap;
693 std::stack<Edge> _edgeStack;
700 template <typename Graph>
701 int countBiNodeConnectedComponents(const Graph& graph);
703 /// \ingroup connectivity
705 /// \brief Checks the graph is bi-node-connected.
707 /// This function checks that the undirected graph is bi-node-connected
708 /// graph. The graph is bi-node-connected if any two undirected edge is
711 /// \param graph The graph.
712 /// \return %True when the graph bi-node-connected.
713 template <typename Graph>
714 bool biNodeConnected(const Graph& graph) {
715 return countBiNodeConnectedComponents(graph) <= 1;
718 /// \ingroup connectivity
720 /// \brief Count the biconnected components.
722 /// This function finds the bi-node-connected components in an undirected
723 /// graph. The biconnected components are the classes of an equivalence
724 /// relation on the undirected edges. Two undirected edge is in relationship
725 /// when they are on same circle.
727 /// \param graph The graph.
728 /// \return The number of components.
729 template <typename Graph>
730 int countBiNodeConnectedComponents(const Graph& graph) {
731 checkConcept<concepts::Graph, Graph>();
732 typedef typename Graph::NodeIt NodeIt;
734 using namespace _connectivity_bits;
736 typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
739 Visitor visitor(graph, compNum);
741 DfsVisit<Graph, Visitor> dfs(graph, visitor);
744 for (NodeIt it(graph); it != INVALID; ++it) {
745 if (!dfs.reached(it)) {
753 /// \ingroup connectivity
755 /// \brief Find the bi-node-connected components.
757 /// This function finds the bi-node-connected components in an undirected
758 /// graph. The bi-node-connected components are the classes of an equivalence
759 /// relation on the undirected edges. Two undirected edge are in relationship
760 /// when they are on same circle.
762 /// \param graph The graph.
763 /// \retval compMap A writable uedge map. The values will be set from 0
764 /// to the number of the biconnected components minus one. Each values
765 /// of the map will be set exactly once, the values of a certain component
766 /// will be set continuously.
767 /// \return The number of components.
769 template <typename Graph, typename EdgeMap>
770 int biNodeConnectedComponents(const Graph& graph,
772 checkConcept<concepts::Graph, Graph>();
773 typedef typename Graph::NodeIt NodeIt;
774 typedef typename Graph::Edge Edge;
775 checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
777 using namespace _connectivity_bits;
779 typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
782 Visitor visitor(graph, compMap, compNum);
784 DfsVisit<Graph, Visitor> dfs(graph, visitor);
787 for (NodeIt it(graph); it != INVALID; ++it) {
788 if (!dfs.reached(it)) {
796 /// \ingroup connectivity
798 /// \brief Find the bi-node-connected cut nodes.
800 /// This function finds the bi-node-connected cut nodes in an undirected
801 /// graph. The bi-node-connected components are the classes of an equivalence
802 /// relation on the undirected edges. Two undirected edges are in
803 /// relationship when they are on same circle. The biconnected components
804 /// are separted by nodes which are the cut nodes of the components.
806 /// \param graph The graph.
807 /// \retval cutMap A writable edge map. The values will be set true when
808 /// the node separate two or more components.
809 /// \return The number of the cut nodes.
810 template <typename Graph, typename NodeMap>
811 int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
812 checkConcept<concepts::Graph, Graph>();
813 typedef typename Graph::Node Node;
814 typedef typename Graph::NodeIt NodeIt;
815 checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
817 using namespace _connectivity_bits;
819 typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
822 Visitor visitor(graph, cutMap, cutNum);
824 DfsVisit<Graph, Visitor> dfs(graph, visitor);
827 for (NodeIt it(graph); it != INVALID; ++it) {
828 if (!dfs.reached(it)) {
836 namespace _connectivity_bits {
838 template <typename Digraph>
839 class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
841 typedef typename Digraph::Node Node;
842 typedef typename Digraph::Arc Arc;
843 typedef typename Digraph::Edge Edge;
845 CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
846 : _graph(graph), _compNum(compNum),
847 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
849 void start(const Node& node) {
850 _predMap.set(node, INVALID);
853 void reach(const Node& node) {
854 _numMap.set(node, _num);
855 _retMap.set(node, _num);
859 void leave(const Node& node) {
860 if (_numMap[node] <= _retMap[node]) {
865 void discover(const Arc& edge) {
866 _predMap.set(_graph.target(edge), edge);
869 void examine(const Arc& edge) {
870 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
873 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
874 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
878 void backtrack(const Arc& edge) {
879 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
880 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
885 const Digraph& _graph;
888 typename Digraph::template NodeMap<int> _numMap;
889 typename Digraph::template NodeMap<int> _retMap;
890 typename Digraph::template NodeMap<Arc> _predMap;
894 template <typename Digraph, typename NodeMap>
895 class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
897 typedef typename Digraph::Node Node;
898 typedef typename Digraph::Arc Arc;
899 typedef typename Digraph::Edge Edge;
901 BiEdgeConnectedComponentsVisitor(const Digraph& graph,
902 NodeMap& compMap, int &compNum)
903 : _graph(graph), _compMap(compMap), _compNum(compNum),
904 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
906 void start(const Node& node) {
907 _predMap.set(node, INVALID);
910 void reach(const Node& node) {
911 _numMap.set(node, _num);
912 _retMap.set(node, _num);
913 _nodeStack.push(node);
917 void leave(const Node& node) {
918 if (_numMap[node] <= _retMap[node]) {
919 while (_nodeStack.top() != node) {
920 _compMap.set(_nodeStack.top(), _compNum);
923 _compMap.set(node, _compNum);
929 void discover(const Arc& edge) {
930 _predMap.set(_graph.target(edge), edge);
933 void examine(const Arc& edge) {
934 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
937 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
938 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
942 void backtrack(const Arc& edge) {
943 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
944 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
949 const Digraph& _graph;
953 typename Digraph::template NodeMap<int> _numMap;
954 typename Digraph::template NodeMap<int> _retMap;
955 typename Digraph::template NodeMap<Arc> _predMap;
956 std::stack<Node> _nodeStack;
961 template <typename Digraph, typename ArcMap>
962 class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
964 typedef typename Digraph::Node Node;
965 typedef typename Digraph::Arc Arc;
966 typedef typename Digraph::Edge Edge;
968 BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
969 ArcMap& cutMap, int &cutNum)
970 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
971 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
973 void start(const Node& node) {
974 _predMap[node] = INVALID;
977 void reach(const Node& node) {
978 _numMap.set(node, _num);
979 _retMap.set(node, _num);
983 void leave(const Node& node) {
984 if (_numMap[node] <= _retMap[node]) {
985 if (_predMap[node] != INVALID) {
986 _cutMap.set(_predMap[node], true);
992 void discover(const Arc& edge) {
993 _predMap.set(_graph.target(edge), edge);
996 void examine(const Arc& edge) {
997 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
1000 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1001 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1005 void backtrack(const Arc& edge) {
1006 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1007 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1012 const Digraph& _graph;
1016 typename Digraph::template NodeMap<int> _numMap;
1017 typename Digraph::template NodeMap<int> _retMap;
1018 typename Digraph::template NodeMap<Arc> _predMap;
1023 template <typename Graph>
1024 int countBiEdgeConnectedComponents(const Graph& graph);
1026 /// \ingroup connectivity
1028 /// \brief Checks that the graph is bi-edge-connected.
1030 /// This function checks that the graph is bi-edge-connected. The undirected
1031 /// graph is bi-edge-connected when any two nodes are connected with two
1032 /// edge-disjoint paths.
1034 /// \param graph The undirected graph.
1035 /// \return The number of components.
1036 template <typename Graph>
1037 bool biEdgeConnected(const Graph& graph) {
1038 return countBiEdgeConnectedComponents(graph) <= 1;
1041 /// \ingroup connectivity
1043 /// \brief Count the bi-edge-connected components.
1045 /// This function count the bi-edge-connected components in an undirected
1046 /// graph. The bi-edge-connected components are the classes of an equivalence
1047 /// relation on the nodes. Two nodes are in relationship when they are
1048 /// connected with at least two edge-disjoint paths.
1050 /// \param graph The undirected graph.
1051 /// \return The number of components.
1052 template <typename Graph>
1053 int countBiEdgeConnectedComponents(const Graph& graph) {
1054 checkConcept<concepts::Graph, Graph>();
1055 typedef typename Graph::NodeIt NodeIt;
1057 using namespace _connectivity_bits;
1059 typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1062 Visitor visitor(graph, compNum);
1064 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1067 for (NodeIt it(graph); it != INVALID; ++it) {
1068 if (!dfs.reached(it)) {
1076 /// \ingroup connectivity
1078 /// \brief Find the bi-edge-connected components.
1080 /// This function finds the bi-edge-connected components in an undirected
1081 /// graph. The bi-edge-connected components are the classes of an equivalence
1082 /// relation on the nodes. Two nodes are in relationship when they are
1083 /// connected at least two edge-disjoint paths.
1085 /// \param graph The graph.
1086 /// \retval compMap A writable node map. The values will be set from 0 to
1087 /// the number of the biconnected components minus one. Each values
1088 /// of the map will be set exactly once, the values of a certain component
1089 /// will be set continuously.
1090 /// \return The number of components.
1092 template <typename Graph, typename NodeMap>
1093 int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
1094 checkConcept<concepts::Graph, Graph>();
1095 typedef typename Graph::NodeIt NodeIt;
1096 typedef typename Graph::Node Node;
1097 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1099 using namespace _connectivity_bits;
1101 typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1104 Visitor visitor(graph, compMap, compNum);
1106 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1109 for (NodeIt it(graph); it != INVALID; ++it) {
1110 if (!dfs.reached(it)) {
1118 /// \ingroup connectivity
1120 /// \brief Find the bi-edge-connected cut edges.
1122 /// This function finds the bi-edge-connected components in an undirected
1123 /// graph. The bi-edge-connected components are the classes of an equivalence
1124 /// relation on the nodes. Two nodes are in relationship when they are
1125 /// connected with at least two edge-disjoint paths. The bi-edge-connected
1126 /// components are separted by edges which are the cut edges of the
1129 /// \param graph The graph.
1130 /// \retval cutMap A writable node map. The values will be set true when the
1131 /// edge is a cut edge.
1132 /// \return The number of cut edges.
1133 template <typename Graph, typename EdgeMap>
1134 int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
1135 checkConcept<concepts::Graph, Graph>();
1136 typedef typename Graph::NodeIt NodeIt;
1137 typedef typename Graph::Edge Edge;
1138 checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
1140 using namespace _connectivity_bits;
1142 typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1145 Visitor visitor(graph, cutMap, cutNum);
1147 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1150 for (NodeIt it(graph); it != INVALID; ++it) {
1151 if (!dfs.reached(it)) {
1160 namespace _connectivity_bits {
1162 template <typename Digraph, typename IntNodeMap>
1163 class TopologicalSortVisitor : public DfsVisitor<Digraph> {
1165 typedef typename Digraph::Node Node;
1166 typedef typename Digraph::Arc edge;
1168 TopologicalSortVisitor(IntNodeMap& order, int num)
1169 : _order(order), _num(num) {}
1171 void leave(const Node& node) {
1172 _order.set(node, --_num);
1182 /// \ingroup connectivity
1184 /// \brief Sort the nodes of a DAG into topolgical order.
1186 /// Sort the nodes of a DAG into topolgical order.
1188 /// \param graph The graph. It must be directed and acyclic.
1189 /// \retval order A writable node map. The values will be set from 0 to
1190 /// the number of the nodes in the graph minus one. Each values of the map
1191 /// will be set exactly once, the values will be set descending order.
1193 /// \see checkedTopologicalSort
1195 template <typename Digraph, typename NodeMap>
1196 void topologicalSort(const Digraph& graph, NodeMap& order) {
1197 using namespace _connectivity_bits;
1199 checkConcept<concepts::Digraph, Digraph>();
1200 checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
1202 typedef typename Digraph::Node Node;
1203 typedef typename Digraph::NodeIt NodeIt;
1204 typedef typename Digraph::Arc Arc;
1206 TopologicalSortVisitor<Digraph, NodeMap>
1207 visitor(order, countNodes(graph));
1209 DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1210 dfs(graph, visitor);
1213 for (NodeIt it(graph); it != INVALID; ++it) {
1214 if (!dfs.reached(it)) {
1221 /// \ingroup connectivity
1223 /// \brief Sort the nodes of a DAG into topolgical order.
1225 /// Sort the nodes of a DAG into topolgical order. It also checks
1226 /// that the given graph is DAG.
1228 /// \param digraph The graph. It must be directed and acyclic.
1229 /// \retval order A readable - writable node map. The values will be set
1230 /// from 0 to the number of the nodes in the graph minus one. Each values
1231 /// of the map will be set exactly once, the values will be set descending
1233 /// \return %False when the graph is not DAG.
1235 /// \see topologicalSort
1237 template <typename Digraph, typename NodeMap>
1238 bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
1239 using namespace _connectivity_bits;
1241 checkConcept<concepts::Digraph, Digraph>();
1242 checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
1245 typedef typename Digraph::Node Node;
1246 typedef typename Digraph::NodeIt NodeIt;
1247 typedef typename Digraph::Arc Arc;
1249 for (NodeIt it(digraph); it != INVALID; ++it) {
1253 TopologicalSortVisitor<Digraph, NodeMap>
1254 visitor(order, countNodes(digraph));
1256 DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1257 dfs(digraph, visitor);
1260 for (NodeIt it(digraph); it != INVALID; ++it) {
1261 if (!dfs.reached(it)) {
1263 while (!dfs.emptyQueue()) {
1264 Arc arc = dfs.nextArc();
1265 Node target = digraph.target(arc);
1266 if (dfs.reached(target) && order[target] == -1) {
1269 dfs.processNextArc();
1276 /// \ingroup connectivity
1278 /// \brief Check that the given directed graph is a DAG.
1280 /// Check that the given directed graph is a DAG. The DAG is
1281 /// an Directed Acyclic Digraph.
1282 /// \return %False when the graph is not DAG.
1284 template <typename Digraph>
1285 bool dag(const Digraph& digraph) {
1287 checkConcept<concepts::Digraph, Digraph>();
1289 typedef typename Digraph::Node Node;
1290 typedef typename Digraph::NodeIt NodeIt;
1291 typedef typename Digraph::Arc Arc;
1293 typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1295 typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1296 Create dfs(digraph);
1298 ProcessedMap processed(digraph);
1299 dfs.processedMap(processed);
1302 for (NodeIt it(digraph); it != INVALID; ++it) {
1303 if (!dfs.reached(it)) {
1305 while (!dfs.emptyQueue()) {
1306 Arc edge = dfs.nextArc();
1307 Node target = digraph.target(edge);
1308 if (dfs.reached(target) && !processed[target]) {
1311 dfs.processNextArc();
1318 /// \ingroup connectivity
1320 /// \brief Check that the given undirected graph is acyclic.
1322 /// Check that the given undirected graph acyclic.
1323 /// \param graph The undirected graph.
1324 /// \return %True when there is no circle in the graph.
1326 template <typename Graph>
1327 bool acyclic(const Graph& graph) {
1328 checkConcept<concepts::Graph, Graph>();
1329 typedef typename Graph::Node Node;
1330 typedef typename Graph::NodeIt NodeIt;
1331 typedef typename Graph::Arc Arc;
1332 Dfs<Graph> dfs(graph);
1334 for (NodeIt it(graph); it != INVALID; ++it) {
1335 if (!dfs.reached(it)) {
1337 while (!dfs.emptyQueue()) {
1338 Arc edge = dfs.nextArc();
1339 Node source = graph.source(edge);
1340 Node target = graph.target(edge);
1341 if (dfs.reached(target) &&
1342 dfs.predArc(source) != graph.oppositeArc(edge)) {
1345 dfs.processNextArc();
1352 /// \ingroup connectivity
1354 /// \brief Check that the given undirected graph is tree.
1356 /// Check that the given undirected graph is tree.
1357 /// \param graph The undirected graph.
1358 /// \return %True when the graph is acyclic and connected.
1359 template <typename Graph>
1360 bool tree(const Graph& graph) {
1361 checkConcept<concepts::Graph, Graph>();
1362 typedef typename Graph::Node Node;
1363 typedef typename Graph::NodeIt NodeIt;
1364 typedef typename Graph::Arc Arc;
1365 Dfs<Graph> dfs(graph);
1367 dfs.addSource(NodeIt(graph));
1368 while (!dfs.emptyQueue()) {
1369 Arc edge = dfs.nextArc();
1370 Node source = graph.source(edge);
1371 Node target = graph.target(edge);
1372 if (dfs.reached(target) &&
1373 dfs.predArc(source) != graph.oppositeArc(edge)) {
1376 dfs.processNextArc();
1378 for (NodeIt it(graph); it != INVALID; ++it) {
1379 if (!dfs.reached(it)) {
1386 namespace _connectivity_bits {
1388 template <typename Digraph>
1389 class BipartiteVisitor : public BfsVisitor<Digraph> {
1391 typedef typename Digraph::Arc Arc;
1392 typedef typename Digraph::Node Node;
1394 BipartiteVisitor(const Digraph& graph, bool& bipartite)
1395 : _graph(graph), _part(graph), _bipartite(bipartite) {}
1397 void start(const Node& node) {
1400 void discover(const Arc& edge) {
1401 _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1403 void examine(const Arc& edge) {
1404 _bipartite = _bipartite &&
1405 _part[_graph.target(edge)] != _part[_graph.source(edge)];
1410 const Digraph& _graph;
1411 typename Digraph::template NodeMap<bool> _part;
1415 template <typename Digraph, typename PartMap>
1416 class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
1418 typedef typename Digraph::Arc Arc;
1419 typedef typename Digraph::Node Node;
1421 BipartitePartitionsVisitor(const Digraph& graph,
1422 PartMap& part, bool& bipartite)
1423 : _graph(graph), _part(part), _bipartite(bipartite) {}
1425 void start(const Node& node) {
1426 _part.set(node, true);
1428 void discover(const Arc& edge) {
1429 _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1431 void examine(const Arc& edge) {
1432 _bipartite = _bipartite &&
1433 _part[_graph.target(edge)] != _part[_graph.source(edge)];
1438 const Digraph& _graph;
1444 /// \ingroup connectivity
1446 /// \brief Check if the given undirected graph is bipartite or not
1448 /// The function checks if the given undirected \c graph graph is bipartite
1449 /// or not. The \ref Bfs algorithm is used to calculate the result.
1450 /// \param graph The undirected graph.
1451 /// \return %True if \c graph is bipartite, %false otherwise.
1452 /// \sa bipartitePartitions
1453 template<typename Graph>
1454 inline bool bipartite(const Graph &graph){
1455 using namespace _connectivity_bits;
1457 checkConcept<concepts::Graph, Graph>();
1459 typedef typename Graph::NodeIt NodeIt;
1460 typedef typename Graph::ArcIt ArcIt;
1462 bool bipartite = true;
1464 BipartiteVisitor<Graph>
1465 visitor(graph, bipartite);
1466 BfsVisit<Graph, BipartiteVisitor<Graph> >
1467 bfs(graph, visitor);
1469 for(NodeIt it(graph); it != INVALID; ++it) {
1470 if(!bfs.reached(it)){
1472 while (!bfs.emptyQueue()) {
1473 bfs.processNextNode();
1474 if (!bipartite) return false;
1481 /// \ingroup connectivity
1483 /// \brief Check if the given undirected graph is bipartite or not
1485 /// The function checks if the given undirected graph is bipartite
1486 /// or not. The \ref Bfs algorithm is used to calculate the result.
1487 /// During the execution, the \c partMap will be set as the two
1488 /// partitions of the graph.
1489 /// \param graph The undirected graph.
1490 /// \retval partMap A writable bool map of nodes. It will be set as the
1491 /// two partitions of the graph.
1492 /// \return %True if \c graph is bipartite, %false otherwise.
1493 template<typename Graph, typename NodeMap>
1494 inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
1495 using namespace _connectivity_bits;
1497 checkConcept<concepts::Graph, Graph>();
1499 typedef typename Graph::Node Node;
1500 typedef typename Graph::NodeIt NodeIt;
1501 typedef typename Graph::ArcIt ArcIt;
1503 bool bipartite = true;
1505 BipartitePartitionsVisitor<Graph, NodeMap>
1506 visitor(graph, partMap, bipartite);
1507 BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
1508 bfs(graph, visitor);
1510 for(NodeIt it(graph); it != INVALID; ++it) {
1511 if(!bfs.reached(it)){
1513 while (!bfs.emptyQueue()) {
1514 bfs.processNextNode();
1515 if (!bipartite) return false;
1522 /// \brief Returns true when there are not loop edges in the graph.
1524 /// Returns true when there are not loop edges in the graph.
1525 template <typename Digraph>
1526 bool loopFree(const Digraph& digraph) {
1527 for (typename Digraph::ArcIt it(digraph); it != INVALID; ++it) {
1528 if (digraph.source(it) == digraph.target(it)) return false;
1533 /// \brief Returns true when there are not parallel edges in the graph.
1535 /// Returns true when there are not parallel edges in the graph.
1536 template <typename Digraph>
1537 bool parallelFree(const Digraph& digraph) {
1538 typename Digraph::template NodeMap<bool> reached(digraph, false);
1539 for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
1540 for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
1541 if (reached[digraph.target(a)]) return false;
1542 reached.set(digraph.target(a), true);
1544 for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
1545 reached.set(digraph.target(a), false);
1551 /// \brief Returns true when there are not loop edges and parallel
1552 /// edges in the graph.
1554 /// Returns true when there are not loop edges and parallel edges in
1556 template <typename Digraph>
1557 bool simpleDigraph(const Digraph& digraph) {
1558 typename Digraph::template NodeMap<bool> reached(digraph, false);
1559 for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
1560 reached.set(n, true);
1561 for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
1562 if (reached[digraph.target(a)]) return false;
1563 reached.set(digraph.target(a), true);
1565 for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
1566 reached.set(digraph.target(a), false);
1568 reached.set(n, false);
1575 #endif //LEMON_CONNECTIVITY_H