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_TOPOLOGY_H
20 #define LEMON_TOPOLOGY_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 _topology_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 StronglyConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
193 typedef typename Digraph::Node Node;
194 typedef typename Digraph::Arc Arc;
196 StronglyConnectedCutEdgesVisitor(const Digraph& digraph,
199 : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
200 _compMap(digraph), _num(0) {
203 void stop(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 _topology_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 RDigraph rdigraph(digraph);
270 typedef DfsVisitor<Digraph> RVisitor;
273 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
275 rdfs.addSource(source);
278 for (NodeIt it(rdigraph); it != INVALID; ++it) {
279 if (!rdfs.reached(it)) {
287 /// \ingroup connectivity
289 /// \brief Count the strongly connected components of a directed graph
291 /// Count the strongly connected components of a directed graph.
292 /// The strongly connected components are the classes of an
293 /// equivalence relation on the nodes of the graph. Two nodes are in
294 /// the same class if they are connected with directed paths in both
297 /// \param graph The graph.
298 /// \return The number of components
299 /// \note By definition, the empty graph has zero
300 /// strongly connected components.
301 template <typename Digraph>
302 int countStronglyConnectedComponents(const Digraph& digraph) {
303 checkConcept<concepts::Digraph, Digraph>();
305 using namespace _topology_bits;
307 typedef typename Digraph::Node Node;
308 typedef typename Digraph::Arc Arc;
309 typedef typename Digraph::NodeIt NodeIt;
310 typedef typename Digraph::ArcIt ArcIt;
312 typedef std::vector<Node> Container;
313 typedef typename Container::iterator Iterator;
315 Container nodes(countNodes(digraph));
316 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
317 Visitor visitor(nodes.begin());
319 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
321 for (NodeIt it(digraph); it != INVALID; ++it) {
322 if (!dfs.reached(it)) {
328 typedef typename Container::reverse_iterator RIterator;
329 typedef ReverseDigraph<const Digraph> RDigraph;
331 RDigraph rdigraph(digraph);
333 typedef DfsVisitor<Digraph> RVisitor;
336 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
341 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
342 if (!rdfs.reached(*it)) {
351 /// \ingroup connectivity
353 /// \brief Find the strongly connected components of a directed graph
355 /// Find the strongly connected components of a directed graph. The
356 /// strongly connected components are the classes of an equivalence
357 /// relation on the nodes of the graph. Two nodes are in
358 /// relationship when there are directed paths between them in both
359 /// direction. In addition, the numbering of components will satisfy
360 /// that there is no arc going from a higher numbered component to
363 /// \param digraph The digraph.
364 /// \retval compMap A writable node map. The values will be set from 0 to
365 /// the number of the strongly connected components minus one. Each value
366 /// of the map will be set exactly once, the values of a certain component
367 /// will be set continuously.
368 /// \return The number of components
370 template <typename Digraph, typename NodeMap>
371 int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
372 checkConcept<concepts::Digraph, Digraph>();
373 typedef typename Digraph::Node Node;
374 typedef typename Digraph::NodeIt NodeIt;
375 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
377 using namespace _topology_bits;
379 typedef std::vector<Node> Container;
380 typedef typename Container::iterator Iterator;
382 Container nodes(countNodes(digraph));
383 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
384 Visitor visitor(nodes.begin());
386 DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
388 for (NodeIt it(digraph); it != INVALID; ++it) {
389 if (!dfs.reached(it)) {
395 typedef typename Container::reverse_iterator RIterator;
396 typedef ReverseDigraph<const Digraph> RDigraph;
398 RDigraph rdigraph(digraph);
402 typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
403 RVisitor rvisitor(compMap, compNum);
405 DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
408 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
409 if (!rdfs.reached(*it)) {
418 /// \ingroup connectivity
420 /// \brief Find the cut arcs of the strongly connected components.
422 /// Find the cut arcs of the strongly connected components.
423 /// The strongly connected components are the classes of an equivalence
424 /// relation on the nodes of the graph. Two nodes are in relationship
425 /// when there are directed paths between them in both direction.
426 /// The strongly connected components are separated by the cut arcs.
428 /// \param graph The graph.
429 /// \retval cutMap A writable node map. The values will be set true when the
430 /// arc is a cut arc.
432 /// \return The number of cut arcs
433 template <typename Digraph, typename ArcMap>
434 int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
435 checkConcept<concepts::Digraph, Digraph>();
436 typedef typename Digraph::Node Node;
437 typedef typename Digraph::Arc Arc;
438 typedef typename Digraph::NodeIt NodeIt;
439 checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
441 using namespace _topology_bits;
443 typedef std::vector<Node> Container;
444 typedef typename Container::iterator Iterator;
446 Container nodes(countNodes(graph));
447 typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
448 Visitor visitor(nodes.begin());
450 DfsVisit<Digraph, Visitor> dfs(graph, visitor);
452 for (NodeIt it(graph); it != INVALID; ++it) {
453 if (!dfs.reached(it)) {
459 typedef typename Container::reverse_iterator RIterator;
460 typedef ReverseDigraph<const Digraph> RDigraph;
462 RDigraph rgraph(graph);
466 typedef StronglyConnectedCutEdgesVisitor<RDigraph, ArcMap> RVisitor;
467 RVisitor rvisitor(rgraph, cutMap, cutNum);
469 DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
472 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
473 if (!rdfs.reached(*it)) {
481 namespace _topology_bits {
483 template <typename Digraph>
484 class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
486 typedef typename Digraph::Node Node;
487 typedef typename Digraph::Arc Arc;
488 typedef typename Digraph::Edge Edge;
490 CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
491 : _graph(graph), _compNum(compNum),
492 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
494 void start(const Node& node) {
495 _predMap.set(node, INVALID);
498 void reach(const Node& node) {
499 _numMap.set(node, _num);
500 _retMap.set(node, _num);
504 void discover(const Arc& edge) {
505 _predMap.set(_graph.target(edge), _graph.source(edge));
508 void examine(const Arc& edge) {
509 if (_graph.source(edge) == _graph.target(edge) &&
510 _graph.direction(edge)) {
514 if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
517 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
518 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
522 void backtrack(const Arc& edge) {
523 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
524 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
526 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
532 const Digraph& _graph;
535 typename Digraph::template NodeMap<int> _numMap;
536 typename Digraph::template NodeMap<int> _retMap;
537 typename Digraph::template NodeMap<Node> _predMap;
541 template <typename Digraph, typename ArcMap>
542 class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
544 typedef typename Digraph::Node Node;
545 typedef typename Digraph::Arc Arc;
546 typedef typename Digraph::Edge Edge;
548 BiNodeConnectedComponentsVisitor(const Digraph& graph,
549 ArcMap& compMap, int &compNum)
550 : _graph(graph), _compMap(compMap), _compNum(compNum),
551 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
553 void start(const Node& node) {
554 _predMap.set(node, INVALID);
557 void reach(const Node& node) {
558 _numMap.set(node, _num);
559 _retMap.set(node, _num);
563 void discover(const Arc& edge) {
564 Node target = _graph.target(edge);
565 _predMap.set(target, edge);
566 _edgeStack.push(edge);
569 void examine(const Arc& edge) {
570 Node source = _graph.source(edge);
571 Node target = _graph.target(edge);
572 if (source == target && _graph.direction(edge)) {
573 _compMap.set(edge, _compNum);
577 if (_numMap[target] < _numMap[source]) {
578 if (_predMap[source] != _graph.oppositeArc(edge)) {
579 _edgeStack.push(edge);
582 if (_predMap[source] != INVALID &&
583 target == _graph.source(_predMap[source])) {
586 if (_retMap[source] > _numMap[target]) {
587 _retMap.set(source, _numMap[target]);
591 void backtrack(const Arc& edge) {
592 Node source = _graph.source(edge);
593 Node target = _graph.target(edge);
594 if (_retMap[source] > _retMap[target]) {
595 _retMap.set(source, _retMap[target]);
597 if (_numMap[source] <= _retMap[target]) {
598 while (_edgeStack.top() != edge) {
599 _compMap.set(_edgeStack.top(), _compNum);
602 _compMap.set(edge, _compNum);
609 const Digraph& _graph;
613 typename Digraph::template NodeMap<int> _numMap;
614 typename Digraph::template NodeMap<int> _retMap;
615 typename Digraph::template NodeMap<Arc> _predMap;
616 std::stack<Edge> _edgeStack;
621 template <typename Digraph, typename NodeMap>
622 class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
624 typedef typename Digraph::Node Node;
625 typedef typename Digraph::Arc Arc;
626 typedef typename Digraph::Edge Edge;
628 BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
630 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
631 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
633 void start(const Node& node) {
634 _predMap.set(node, INVALID);
638 void reach(const Node& node) {
639 _numMap.set(node, _num);
640 _retMap.set(node, _num);
644 void discover(const Arc& edge) {
645 _predMap.set(_graph.target(edge), _graph.source(edge));
648 void examine(const Arc& edge) {
649 if (_graph.source(edge) == _graph.target(edge) &&
650 _graph.direction(edge)) {
651 if (!_cutMap[_graph.source(edge)]) {
652 _cutMap.set(_graph.source(edge), true);
657 if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
658 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
659 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
663 void backtrack(const Arc& edge) {
664 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
665 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
667 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
668 if (_predMap[_graph.source(edge)] != INVALID) {
669 if (!_cutMap[_graph.source(edge)]) {
670 _cutMap.set(_graph.source(edge), true);
673 } else if (rootCut) {
674 if (!_cutMap[_graph.source(edge)]) {
675 _cutMap.set(_graph.source(edge), true);
685 const Digraph& _graph;
689 typename Digraph::template NodeMap<int> _numMap;
690 typename Digraph::template NodeMap<int> _retMap;
691 typename Digraph::template NodeMap<Node> _predMap;
692 std::stack<Edge> _edgeStack;
699 template <typename Graph>
700 int countBiNodeConnectedComponents(const Graph& graph);
702 /// \ingroup connectivity
704 /// \brief Checks the graph is bi-node-connected.
706 /// This function checks that the undirected graph is bi-node-connected
707 /// graph. The graph is bi-node-connected if any two undirected edge is
710 /// \param graph The graph.
711 /// \return %True when the graph bi-node-connected.
712 template <typename Graph>
713 bool biNodeConnected(const Graph& graph) {
714 return countBiNodeConnectedComponents(graph) <= 1;
717 /// \ingroup connectivity
719 /// \brief Count the biconnected components.
721 /// This function finds the bi-node-connected components in an undirected
722 /// graph. The biconnected components are the classes of an equivalence
723 /// relation on the undirected edges. Two undirected edge is in relationship
724 /// when they are on same circle.
726 /// \param graph The graph.
727 /// \return The number of components.
728 template <typename Graph>
729 int countBiNodeConnectedComponents(const Graph& graph) {
730 checkConcept<concepts::Graph, Graph>();
731 typedef typename Graph::NodeIt NodeIt;
733 using namespace _topology_bits;
735 typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
738 Visitor visitor(graph, compNum);
740 DfsVisit<Graph, Visitor> dfs(graph, visitor);
743 for (NodeIt it(graph); it != INVALID; ++it) {
744 if (!dfs.reached(it)) {
752 /// \ingroup connectivity
754 /// \brief Find the bi-node-connected components.
756 /// This function finds the bi-node-connected components in an undirected
757 /// graph. The bi-node-connected components are the classes of an equivalence
758 /// relation on the undirected edges. Two undirected edge are in relationship
759 /// when they are on same circle.
761 /// \param graph The graph.
762 /// \retval compMap A writable uedge map. The values will be set from 0
763 /// to the number of the biconnected components minus one. Each values
764 /// of the map will be set exactly once, the values of a certain component
765 /// will be set continuously.
766 /// \return The number of components.
768 template <typename Graph, typename EdgeMap>
769 int biNodeConnectedComponents(const Graph& graph,
771 checkConcept<concepts::Graph, Graph>();
772 typedef typename Graph::NodeIt NodeIt;
773 typedef typename Graph::Edge Edge;
774 checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
776 using namespace _topology_bits;
778 typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
781 Visitor visitor(graph, compMap, compNum);
783 DfsVisit<Graph, Visitor> dfs(graph, visitor);
786 for (NodeIt it(graph); it != INVALID; ++it) {
787 if (!dfs.reached(it)) {
795 /// \ingroup connectivity
797 /// \brief Find the bi-node-connected cut nodes.
799 /// This function finds the bi-node-connected cut nodes in an undirected
800 /// graph. The bi-node-connected components are the classes of an equivalence
801 /// relation on the undirected edges. Two undirected edges are in
802 /// relationship when they are on same circle. The biconnected components
803 /// are separted by nodes which are the cut nodes of the components.
805 /// \param graph The graph.
806 /// \retval cutMap A writable edge map. The values will be set true when
807 /// the node separate two or more components.
808 /// \return The number of the cut nodes.
809 template <typename Graph, typename NodeMap>
810 int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
811 checkConcept<concepts::Graph, Graph>();
812 typedef typename Graph::Node Node;
813 typedef typename Graph::NodeIt NodeIt;
814 checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
816 using namespace _topology_bits;
818 typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
821 Visitor visitor(graph, cutMap, cutNum);
823 DfsVisit<Graph, Visitor> dfs(graph, visitor);
826 for (NodeIt it(graph); it != INVALID; ++it) {
827 if (!dfs.reached(it)) {
835 namespace _topology_bits {
837 template <typename Digraph>
838 class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
840 typedef typename Digraph::Node Node;
841 typedef typename Digraph::Arc Arc;
842 typedef typename Digraph::Edge Edge;
844 CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
845 : _graph(graph), _compNum(compNum),
846 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
848 void start(const Node& node) {
849 _predMap.set(node, INVALID);
852 void reach(const Node& node) {
853 _numMap.set(node, _num);
854 _retMap.set(node, _num);
858 void leave(const Node& node) {
859 if (_numMap[node] <= _retMap[node]) {
864 void discover(const Arc& edge) {
865 _predMap.set(_graph.target(edge), edge);
868 void examine(const Arc& edge) {
869 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
872 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
873 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
877 void backtrack(const Arc& edge) {
878 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
879 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
884 const Digraph& _graph;
887 typename Digraph::template NodeMap<int> _numMap;
888 typename Digraph::template NodeMap<int> _retMap;
889 typename Digraph::template NodeMap<Arc> _predMap;
893 template <typename Digraph, typename NodeMap>
894 class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
896 typedef typename Digraph::Node Node;
897 typedef typename Digraph::Arc Arc;
898 typedef typename Digraph::Edge Edge;
900 BiEdgeConnectedComponentsVisitor(const Digraph& graph,
901 NodeMap& compMap, int &compNum)
902 : _graph(graph), _compMap(compMap), _compNum(compNum),
903 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
905 void start(const Node& node) {
906 _predMap.set(node, INVALID);
909 void reach(const Node& node) {
910 _numMap.set(node, _num);
911 _retMap.set(node, _num);
912 _nodeStack.push(node);
916 void leave(const Node& node) {
917 if (_numMap[node] <= _retMap[node]) {
918 while (_nodeStack.top() != node) {
919 _compMap.set(_nodeStack.top(), _compNum);
922 _compMap.set(node, _compNum);
928 void discover(const Arc& edge) {
929 _predMap.set(_graph.target(edge), edge);
932 void examine(const Arc& edge) {
933 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
936 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
937 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
941 void backtrack(const Arc& edge) {
942 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
943 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
948 const Digraph& _graph;
952 typename Digraph::template NodeMap<int> _numMap;
953 typename Digraph::template NodeMap<int> _retMap;
954 typename Digraph::template NodeMap<Arc> _predMap;
955 std::stack<Node> _nodeStack;
960 template <typename Digraph, typename ArcMap>
961 class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
963 typedef typename Digraph::Node Node;
964 typedef typename Digraph::Arc Arc;
965 typedef typename Digraph::Edge Edge;
967 BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
968 ArcMap& cutMap, int &cutNum)
969 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
970 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
972 void start(const Node& node) {
973 _predMap[node] = INVALID;
976 void reach(const Node& node) {
977 _numMap.set(node, _num);
978 _retMap.set(node, _num);
982 void leave(const Node& node) {
983 if (_numMap[node] <= _retMap[node]) {
984 if (_predMap[node] != INVALID) {
985 _cutMap.set(_predMap[node], true);
991 void discover(const Arc& edge) {
992 _predMap.set(_graph.target(edge), edge);
995 void examine(const Arc& edge) {
996 if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
999 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1000 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1004 void backtrack(const Arc& edge) {
1005 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1006 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1011 const Digraph& _graph;
1015 typename Digraph::template NodeMap<int> _numMap;
1016 typename Digraph::template NodeMap<int> _retMap;
1017 typename Digraph::template NodeMap<Arc> _predMap;
1022 template <typename Graph>
1023 int countBiEdgeConnectedComponents(const Graph& graph);
1025 /// \ingroup connectivity
1027 /// \brief Checks that the graph is bi-edge-connected.
1029 /// This function checks that the graph is bi-edge-connected. The undirected
1030 /// graph is bi-edge-connected when any two nodes are connected with two
1031 /// edge-disjoint paths.
1033 /// \param graph The undirected graph.
1034 /// \return The number of components.
1035 template <typename Graph>
1036 bool biEdgeConnected(const Graph& graph) {
1037 return countBiEdgeConnectedComponents(graph) <= 1;
1040 /// \ingroup connectivity
1042 /// \brief Count the bi-edge-connected components.
1044 /// This function count the bi-edge-connected components in an undirected
1045 /// graph. The bi-edge-connected components are the classes of an equivalence
1046 /// relation on the nodes. Two nodes are in relationship when they are
1047 /// connected with at least two edge-disjoint paths.
1049 /// \param graph The undirected graph.
1050 /// \return The number of components.
1051 template <typename Graph>
1052 int countBiEdgeConnectedComponents(const Graph& graph) {
1053 checkConcept<concepts::Graph, Graph>();
1054 typedef typename Graph::NodeIt NodeIt;
1056 using namespace _topology_bits;
1058 typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1061 Visitor visitor(graph, compNum);
1063 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1066 for (NodeIt it(graph); it != INVALID; ++it) {
1067 if (!dfs.reached(it)) {
1075 /// \ingroup connectivity
1077 /// \brief Find the bi-edge-connected components.
1079 /// This function finds the bi-edge-connected components in an undirected
1080 /// graph. The bi-edge-connected components are the classes of an equivalence
1081 /// relation on the nodes. Two nodes are in relationship when they are
1082 /// connected at least two edge-disjoint paths.
1084 /// \param graph The graph.
1085 /// \retval compMap A writable node map. The values will be set from 0 to
1086 /// the number of the biconnected components minus one. Each values
1087 /// of the map will be set exactly once, the values of a certain component
1088 /// will be set continuously.
1089 /// \return The number of components.
1091 template <typename Graph, typename NodeMap>
1092 int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
1093 checkConcept<concepts::Graph, Graph>();
1094 typedef typename Graph::NodeIt NodeIt;
1095 typedef typename Graph::Node Node;
1096 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1098 using namespace _topology_bits;
1100 typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1103 Visitor visitor(graph, compMap, compNum);
1105 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1108 for (NodeIt it(graph); it != INVALID; ++it) {
1109 if (!dfs.reached(it)) {
1117 /// \ingroup connectivity
1119 /// \brief Find the bi-edge-connected cut edges.
1121 /// This function finds the bi-edge-connected components in an undirected
1122 /// graph. The bi-edge-connected components are the classes of an equivalence
1123 /// relation on the nodes. Two nodes are in relationship when they are
1124 /// connected with at least two edge-disjoint paths. The bi-edge-connected
1125 /// components are separted by edges which are the cut edges of the
1128 /// \param graph The graph.
1129 /// \retval cutMap A writable node map. The values will be set true when the
1130 /// edge is a cut edge.
1131 /// \return The number of cut edges.
1132 template <typename Graph, typename EdgeMap>
1133 int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
1134 checkConcept<concepts::Graph, Graph>();
1135 typedef typename Graph::NodeIt NodeIt;
1136 typedef typename Graph::Edge Edge;
1137 checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
1139 using namespace _topology_bits;
1141 typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1144 Visitor visitor(graph, cutMap, cutNum);
1146 DfsVisit<Graph, Visitor> dfs(graph, visitor);
1149 for (NodeIt it(graph); it != INVALID; ++it) {
1150 if (!dfs.reached(it)) {
1159 namespace _topology_bits {
1161 template <typename Digraph, typename IntNodeMap>
1162 class TopologicalSortVisitor : public DfsVisitor<Digraph> {
1164 typedef typename Digraph::Node Node;
1165 typedef typename Digraph::Arc edge;
1167 TopologicalSortVisitor(IntNodeMap& order, int num)
1168 : _order(order), _num(num) {}
1170 void leave(const Node& node) {
1171 _order.set(node, --_num);
1181 /// \ingroup connectivity
1183 /// \brief Sort the nodes of a DAG into topolgical order.
1185 /// Sort the nodes of a DAG into topolgical order.
1187 /// \param graph The graph. It must be directed and acyclic.
1188 /// \retval order A writable node map. The values will be set from 0 to
1189 /// the number of the nodes in the graph minus one. Each values of the map
1190 /// will be set exactly once, the values will be set descending order.
1192 /// \see checkedTopologicalSort
1194 template <typename Digraph, typename NodeMap>
1195 void topologicalSort(const Digraph& graph, NodeMap& order) {
1196 using namespace _topology_bits;
1198 checkConcept<concepts::Digraph, Digraph>();
1199 checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
1201 typedef typename Digraph::Node Node;
1202 typedef typename Digraph::NodeIt NodeIt;
1203 typedef typename Digraph::Arc Arc;
1205 TopologicalSortVisitor<Digraph, NodeMap>
1206 visitor(order, countNodes(graph));
1208 DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1209 dfs(graph, visitor);
1212 for (NodeIt it(graph); it != INVALID; ++it) {
1213 if (!dfs.reached(it)) {
1220 /// \ingroup connectivity
1222 /// \brief Sort the nodes of a DAG into topolgical order.
1224 /// Sort the nodes of a DAG into topolgical order. It also checks
1225 /// that the given graph is DAG.
1227 /// \param graph The graph. It must be directed and acyclic.
1228 /// \retval order A readable - writable node map. The values will be set
1229 /// from 0 to the number of the nodes in the graph minus one. Each values
1230 /// of the map will be set exactly once, the values will be set descending
1232 /// \return %False when the graph is not DAG.
1234 /// \see topologicalSort
1236 template <typename Digraph, typename NodeMap>
1237 bool checkedTopologicalSort(const Digraph& graph, NodeMap& order) {
1238 using namespace _topology_bits;
1240 checkConcept<concepts::Digraph, Digraph>();
1241 checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
1244 typedef typename Digraph::Node Node;
1245 typedef typename Digraph::NodeIt NodeIt;
1246 typedef typename Digraph::Arc Arc;
1248 order = constMap<Node, int, -1>();
1250 TopologicalSortVisitor<Digraph, NodeMap>
1251 visitor(order, countNodes(graph));
1253 DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1254 dfs(graph, visitor);
1257 for (NodeIt it(graph); it != INVALID; ++it) {
1258 if (!dfs.reached(it)) {
1260 while (!dfs.emptyQueue()) {
1261 Arc edge = dfs.nextArc();
1262 Node target = graph.target(edge);
1263 if (dfs.reached(target) && order[target] == -1) {
1266 dfs.processNextArc();
1273 /// \ingroup connectivity
1275 /// \brief Check that the given directed graph is a DAG.
1277 /// Check that the given directed graph is a DAG. The DAG is
1278 /// an Directed Acyclic Digraph.
1279 /// \return %False when the graph is not DAG.
1281 template <typename Digraph>
1282 bool dag(const Digraph& graph) {
1284 checkConcept<concepts::Digraph, Digraph>();
1286 typedef typename Digraph::Node Node;
1287 typedef typename Digraph::NodeIt NodeIt;
1288 typedef typename Digraph::Arc Arc;
1290 typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1292 typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1295 ProcessedMap processed(graph);
1296 dfs.processedMap(processed);
1299 for (NodeIt it(graph); it != INVALID; ++it) {
1300 if (!dfs.reached(it)) {
1302 while (!dfs.emptyQueue()) {
1303 Arc edge = dfs.nextArc();
1304 Node target = graph.target(edge);
1305 if (dfs.reached(target) && !processed[target]) {
1308 dfs.processNextArc();
1315 /// \ingroup connectivity
1317 /// \brief Check that the given undirected graph is acyclic.
1319 /// Check that the given undirected graph acyclic.
1320 /// \param graph The undirected graph.
1321 /// \return %True when there is no circle in the graph.
1323 template <typename Graph>
1324 bool acyclic(const Graph& graph) {
1325 checkConcept<concepts::Graph, Graph>();
1326 typedef typename Graph::Node Node;
1327 typedef typename Graph::NodeIt NodeIt;
1328 typedef typename Graph::Arc Arc;
1329 Dfs<Graph> dfs(graph);
1331 for (NodeIt it(graph); it != INVALID; ++it) {
1332 if (!dfs.reached(it)) {
1334 while (!dfs.emptyQueue()) {
1335 Arc edge = dfs.nextArc();
1336 Node source = graph.source(edge);
1337 Node target = graph.target(edge);
1338 if (dfs.reached(target) &&
1339 dfs.predArc(source) != graph.oppositeArc(edge)) {
1342 dfs.processNextArc();
1349 /// \ingroup connectivity
1351 /// \brief Check that the given undirected graph is tree.
1353 /// Check that the given undirected graph is tree.
1354 /// \param graph The undirected graph.
1355 /// \return %True when the graph is acyclic and connected.
1356 template <typename Graph>
1357 bool tree(const Graph& graph) {
1358 checkConcept<concepts::Graph, Graph>();
1359 typedef typename Graph::Node Node;
1360 typedef typename Graph::NodeIt NodeIt;
1361 typedef typename Graph::Arc Arc;
1362 Dfs<Graph> dfs(graph);
1364 dfs.addSource(NodeIt(graph));
1365 while (!dfs.emptyQueue()) {
1366 Arc edge = dfs.nextArc();
1367 Node source = graph.source(edge);
1368 Node target = graph.target(edge);
1369 if (dfs.reached(target) &&
1370 dfs.predArc(source) != graph.oppositeArc(edge)) {
1373 dfs.processNextArc();
1375 for (NodeIt it(graph); it != INVALID; ++it) {
1376 if (!dfs.reached(it)) {
1383 namespace _topology_bits {
1385 template <typename Digraph>
1386 class BipartiteVisitor : public BfsVisitor<Digraph> {
1388 typedef typename Digraph::Arc Arc;
1389 typedef typename Digraph::Node Node;
1391 BipartiteVisitor(const Digraph& graph, bool& bipartite)
1392 : _graph(graph), _part(graph), _bipartite(bipartite) {}
1394 void start(const Node& node) {
1397 void discover(const Arc& edge) {
1398 _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1400 void examine(const Arc& edge) {
1401 _bipartite = _bipartite &&
1402 _part[_graph.target(edge)] != _part[_graph.source(edge)];
1407 const Digraph& _graph;
1408 typename Digraph::template NodeMap<bool> _part;
1412 template <typename Digraph, typename PartMap>
1413 class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
1415 typedef typename Digraph::Arc Arc;
1416 typedef typename Digraph::Node Node;
1418 BipartitePartitionsVisitor(const Digraph& graph,
1419 PartMap& part, bool& bipartite)
1420 : _graph(graph), _part(part), _bipartite(bipartite) {}
1422 void start(const Node& node) {
1423 _part.set(node, true);
1425 void discover(const Arc& edge) {
1426 _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1428 void examine(const Arc& edge) {
1429 _bipartite = _bipartite &&
1430 _part[_graph.target(edge)] != _part[_graph.source(edge)];
1435 const Digraph& _graph;
1441 /// \ingroup connectivity
1443 /// \brief Check if the given undirected graph is bipartite or not
1445 /// The function checks if the given undirected \c graph graph is bipartite
1446 /// or not. The \ref Bfs algorithm is used to calculate the result.
1447 /// \param graph The undirected graph.
1448 /// \return %True if \c graph is bipartite, %false otherwise.
1449 /// \sa bipartitePartitions
1450 template<typename Graph>
1451 inline bool bipartite(const Graph &graph){
1452 using namespace _topology_bits;
1454 checkConcept<concepts::Graph, Graph>();
1456 typedef typename Graph::NodeIt NodeIt;
1457 typedef typename Graph::ArcIt ArcIt;
1459 bool bipartite = true;
1461 BipartiteVisitor<Graph>
1462 visitor(graph, bipartite);
1463 BfsVisit<Graph, BipartiteVisitor<Graph> >
1464 bfs(graph, visitor);
1466 for(NodeIt it(graph); it != INVALID; ++it) {
1467 if(!bfs.reached(it)){
1469 while (!bfs.emptyQueue()) {
1470 bfs.processNextNode();
1471 if (!bipartite) return false;
1478 /// \ingroup connectivity
1480 /// \brief Check if the given undirected graph is bipartite or not
1482 /// The function checks if the given undirected graph is bipartite
1483 /// or not. The \ref Bfs algorithm is used to calculate the result.
1484 /// During the execution, the \c partMap will be set as the two
1485 /// partitions of the graph.
1486 /// \param graph The undirected graph.
1487 /// \retval partMap A writable bool map of nodes. It will be set as the
1488 /// two partitions of the graph.
1489 /// \return %True if \c graph is bipartite, %false otherwise.
1490 template<typename Graph, typename NodeMap>
1491 inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
1492 using namespace _topology_bits;
1494 checkConcept<concepts::Graph, Graph>();
1496 typedef typename Graph::Node Node;
1497 typedef typename Graph::NodeIt NodeIt;
1498 typedef typename Graph::ArcIt ArcIt;
1500 bool bipartite = true;
1502 BipartitePartitionsVisitor<Graph, NodeMap>
1503 visitor(graph, partMap, bipartite);
1504 BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
1505 bfs(graph, visitor);
1507 for(NodeIt it(graph); it != INVALID; ++it) {
1508 if(!bfs.reached(it)){
1510 while (!bfs.emptyQueue()) {
1511 bfs.processNextNode();
1512 if (!bipartite) return false;
1519 /// \brief Returns true when there are not loop edges in the graph.
1521 /// Returns true when there are not loop edges in the graph.
1522 template <typename Digraph>
1523 bool loopFree(const Digraph& graph) {
1524 for (typename Digraph::ArcIt it(graph); it != INVALID; ++it) {
1525 if (graph.source(it) == graph.target(it)) return false;
1530 /// \brief Returns true when there are not parallel edges in the graph.
1532 /// Returns true when there are not parallel edges in the graph.
1533 template <typename Digraph>
1534 bool parallelFree(const Digraph& graph) {
1535 typename Digraph::template NodeMap<bool> reached(graph, false);
1536 for (typename Digraph::NodeIt n(graph); n != INVALID; ++n) {
1537 for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
1538 if (reached[graph.target(e)]) return false;
1539 reached.set(graph.target(e), true);
1541 for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
1542 reached.set(graph.target(e), false);
1548 /// \brief Returns true when there are not loop edges and parallel
1549 /// edges in the graph.
1551 /// Returns true when there are not loop edges and parallel edges in
1553 template <typename Digraph>
1554 bool simpleDigraph(const Digraph& graph) {
1555 typename Digraph::template NodeMap<bool> reached(graph, false);
1556 for (typename Digraph::NodeIt n(graph); n != INVALID; ++n) {
1557 reached.set(n, true);
1558 for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
1559 if (reached[graph.target(e)]) return false;
1560 reached.set(graph.target(e), true);
1562 for (typename Digraph::OutArcIt e(graph, n); e != INVALID; ++e) {
1563 reached.set(graph.target(e), false);
1565 reached.set(n, false);
1572 #endif //LEMON_TOPOLOGY_H