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/graph_utils.h>
25 #include <lemon/graph_adaptor.h>
26 #include <lemon/maps.h>
28 #include <lemon/concepts/graph.h>
29 #include <lemon/concepts/ugraph.h>
30 #include <lemon/concept_check.h>
32 #include <lemon/bin_heap.h>
33 #include <lemon/bucket_heap.h>
38 /// \ingroup graph_prop
40 /// \brief Topology related algorithms
42 /// Topology related algorithms
46 /// \ingroup graph_prop
48 /// \brief Check that the given undirected graph is connected.
50 /// Check that the given undirected graph connected.
51 /// \param graph The undirected graph.
52 /// \return %True when there is path between any two nodes in the graph.
53 /// \note By definition, the empty graph is connected.
54 template <typename UGraph>
55 bool connected(const UGraph& graph) {
56 checkConcept<concepts::UGraph, UGraph>();
57 typedef typename UGraph::NodeIt NodeIt;
58 if (NodeIt(graph) == INVALID) return true;
59 Dfs<UGraph> dfs(graph);
60 dfs.run(NodeIt(graph));
61 for (NodeIt it(graph); it != INVALID; ++it) {
62 if (!dfs.reached(it)) {
69 /// \ingroup graph_prop
71 /// \brief Count the number of connected components of an undirected graph
73 /// Count the number of connected components of an undirected graph
75 /// \param graph The graph. It should be undirected.
76 /// \return The number of components
77 /// \note By definition, the empty graph consists
78 /// of zero connected components.
79 template <typename UGraph>
80 int countConnectedComponents(const UGraph &graph) {
81 checkConcept<concepts::UGraph, UGraph>();
82 typedef typename UGraph::Node Node;
83 typedef typename UGraph::Edge Edge;
85 typedef NullMap<Node, Edge> PredMap;
86 typedef NullMap<Node, int> DistMap;
89 typename Bfs<UGraph>::
90 template DefPredMap<PredMap>::
91 template DefDistMap<DistMap>::
101 for(typename UGraph::NodeIt n(graph); n != INVALID; ++n) {
102 if (!bfs.reached(n)) {
111 /// \ingroup graph_prop
113 /// \brief Find the connected components of an undirected graph
115 /// Find the connected components of an undirected graph.
117 /// \image html connected_components.png
118 /// \image latex connected_components.eps "Connected components" width=\textwidth
120 /// \param graph The graph. It should be undirected.
121 /// \retval compMap A writable node map. The values will be set from 0 to
122 /// the number of the connected components minus one. Each values of the map
123 /// will be set exactly once, the values of a certain component will be
124 /// set continuously.
125 /// \return The number of components
127 template <class UGraph, class NodeMap>
128 int connectedComponents(const UGraph &graph, NodeMap &compMap) {
129 checkConcept<concepts::UGraph, UGraph>();
130 typedef typename UGraph::Node Node;
131 typedef typename UGraph::Edge Edge;
132 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
134 typedef NullMap<Node, Edge> PredMap;
135 typedef NullMap<Node, int> DistMap;
138 typename Bfs<UGraph>::
139 template DefPredMap<PredMap>::
140 template DefDistMap<DistMap>::
144 bfs.predMap(predMap);
147 bfs.distMap(distMap);
150 for(typename UGraph::NodeIt n(graph); n != INVALID; ++n) {
151 if(!bfs.reached(n)) {
153 while (!bfs.emptyQueue()) {
154 compMap.set(bfs.nextNode(), compNum);
155 bfs.processNextNode();
163 namespace _topology_bits {
165 template <typename Graph, typename Iterator >
166 struct LeaveOrderVisitor : public DfsVisitor<Graph> {
168 typedef typename Graph::Node Node;
169 LeaveOrderVisitor(Iterator it) : _it(it) {}
171 void leave(const Node& node) {
179 template <typename Graph, typename Map>
180 struct FillMapVisitor : public DfsVisitor<Graph> {
182 typedef typename Graph::Node Node;
183 typedef typename Map::Value Value;
185 FillMapVisitor(Map& map, Value& value)
186 : _map(map), _value(value) {}
188 void reach(const Node& node) {
189 _map.set(node, _value);
196 template <typename Graph, typename EdgeMap>
197 struct StronglyConnectedCutEdgesVisitor : public DfsVisitor<Graph> {
199 typedef typename Graph::Node Node;
200 typedef typename Graph::Edge Edge;
202 StronglyConnectedCutEdgesVisitor(const Graph& graph, EdgeMap& cutMap,
204 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
205 _compMap(graph), _num(0) {
208 void stop(const Node&) {
212 void reach(const Node& node) {
213 _compMap.set(node, _num);
216 void examine(const Edge& edge) {
217 if (_compMap[_graph.source(edge)] != _compMap[_graph.target(edge)]) {
218 _cutMap.set(edge, true);
227 typename Graph::template NodeMap<int> _compMap;
234 /// \ingroup graph_prop
236 /// \brief Check that the given directed graph is strongly connected.
238 /// Check that the given directed graph is strongly connected. The
239 /// graph is strongly connected when any two nodes of the graph are
240 /// connected with directed paths in both direction.
241 /// \return %False when the graph is not strongly connected.
244 /// \note By definition, the empty graph is strongly connected.
245 template <typename Graph>
246 bool stronglyConnected(const Graph& graph) {
247 checkConcept<concepts::Graph, Graph>();
249 typedef typename Graph::Node Node;
250 typedef typename Graph::NodeIt NodeIt;
252 if (NodeIt(graph) == INVALID) return true;
254 using namespace _topology_bits;
256 typedef DfsVisitor<Graph> Visitor;
259 DfsVisit<Graph, Visitor> dfs(graph, visitor);
261 dfs.addSource(NodeIt(graph));
264 for (NodeIt it(graph); it != INVALID; ++it) {
265 if (!dfs.reached(it)) {
270 typedef RevGraphAdaptor<const Graph> RGraph;
271 RGraph rgraph(graph);
273 typedef DfsVisitor<Graph> RVisitor;
276 DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
278 rdfs.addSource(NodeIt(graph));
281 for (NodeIt it(graph); it != INVALID; ++it) {
282 if (!rdfs.reached(it)) {
290 /// \ingroup graph_prop
292 /// \brief Count the strongly connected components of a directed graph
294 /// Count the strongly connected components of a directed graph.
295 /// The strongly connected components are the classes of an
296 /// equivalence relation on the nodes of the graph. Two nodes are in
297 /// the same class if they are connected with directed paths in both
300 /// \param graph The graph.
301 /// \return The number of components
302 /// \note By definition, the empty graph has zero
303 /// strongly connected components.
304 template <typename Graph>
305 int countStronglyConnectedComponents(const Graph& graph) {
306 checkConcept<concepts::Graph, Graph>();
308 using namespace _topology_bits;
310 typedef typename Graph::Node Node;
311 typedef typename Graph::Edge Edge;
312 typedef typename Graph::NodeIt NodeIt;
313 typedef typename Graph::EdgeIt EdgeIt;
315 typedef std::vector<Node> Container;
316 typedef typename Container::iterator Iterator;
318 Container nodes(countNodes(graph));
319 typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
320 Visitor visitor(nodes.begin());
322 DfsVisit<Graph, Visitor> dfs(graph, visitor);
324 for (NodeIt it(graph); it != INVALID; ++it) {
325 if (!dfs.reached(it)) {
331 typedef typename Container::reverse_iterator RIterator;
332 typedef RevGraphAdaptor<const Graph> RGraph;
334 RGraph rgraph(graph);
336 typedef DfsVisitor<Graph> RVisitor;
339 DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
344 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
345 if (!rdfs.reached(*it)) {
354 /// \ingroup graph_prop
356 /// \brief Find the strongly connected components of a directed graph
358 /// Find the strongly connected components of a directed graph. The
359 /// strongly connected components are the classes of an equivalence
360 /// relation on the nodes of the graph. Two nodes are in
361 /// relationship when there are directed paths between them in both
362 /// direction. In addition, the numbering of components will satisfy
363 /// that there is no edge going from a higher numbered component to
366 /// \image html strongly_connected_components.png
367 /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
369 /// \param graph The graph.
370 /// \retval compMap A writable node map. The values will be set from 0 to
371 /// the number of the strongly connected components minus one. Each value
372 /// of the map will be set exactly once, the values of a certain component
373 /// will be set continuously.
374 /// \return The number of components
376 template <typename Graph, typename NodeMap>
377 int stronglyConnectedComponents(const Graph& graph, NodeMap& compMap) {
378 checkConcept<concepts::Graph, Graph>();
379 typedef typename Graph::Node Node;
380 typedef typename Graph::NodeIt NodeIt;
381 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
383 using namespace _topology_bits;
385 typedef std::vector<Node> Container;
386 typedef typename Container::iterator Iterator;
388 Container nodes(countNodes(graph));
389 typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
390 Visitor visitor(nodes.begin());
392 DfsVisit<Graph, Visitor> dfs(graph, visitor);
394 for (NodeIt it(graph); it != INVALID; ++it) {
395 if (!dfs.reached(it)) {
401 typedef typename Container::reverse_iterator RIterator;
402 typedef RevGraphAdaptor<const Graph> RGraph;
404 RGraph rgraph(graph);
408 typedef FillMapVisitor<RGraph, NodeMap> RVisitor;
409 RVisitor rvisitor(compMap, compNum);
411 DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
414 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
415 if (!rdfs.reached(*it)) {
424 /// \ingroup graph_prop
426 /// \brief Find the cut edges of the strongly connected components.
428 /// Find the cut edges of the strongly connected components.
429 /// The strongly connected components are the classes of an equivalence
430 /// relation on the nodes of the graph. Two nodes are in relationship
431 /// when there are directed paths between them in both direction.
432 /// The strongly connected components are separated by the cut edges.
434 /// \param graph The graph.
435 /// \retval cutMap A writable node map. The values will be set true when the
436 /// edge is a cut edge.
438 /// \return The number of cut edges
439 template <typename Graph, typename EdgeMap>
440 int stronglyConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
441 checkConcept<concepts::Graph, Graph>();
442 typedef typename Graph::Node Node;
443 typedef typename Graph::Edge Edge;
444 typedef typename Graph::NodeIt NodeIt;
445 checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
447 using namespace _topology_bits;
449 typedef std::vector<Node> Container;
450 typedef typename Container::iterator Iterator;
452 Container nodes(countNodes(graph));
453 typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
454 Visitor visitor(nodes.begin());
456 DfsVisit<Graph, Visitor> dfs(graph, visitor);
458 for (NodeIt it(graph); it != INVALID; ++it) {
459 if (!dfs.reached(it)) {
465 typedef typename Container::reverse_iterator RIterator;
466 typedef RevGraphAdaptor<const Graph> RGraph;
468 RGraph rgraph(graph);
472 typedef StronglyConnectedCutEdgesVisitor<RGraph, EdgeMap> RVisitor;
473 RVisitor rvisitor(rgraph, cutMap, cutNum);
475 DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
478 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
479 if (!rdfs.reached(*it)) {
487 namespace _topology_bits {
489 template <typename Graph>
490 class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Graph> {
492 typedef typename Graph::Node Node;
493 typedef typename Graph::Edge Edge;
494 typedef typename Graph::UEdge UEdge;
496 CountBiNodeConnectedComponentsVisitor(const Graph& graph, int &compNum)
497 : _graph(graph), _compNum(compNum),
498 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
500 void start(const Node& node) {
501 _predMap.set(node, INVALID);
504 void reach(const Node& node) {
505 _numMap.set(node, _num);
506 _retMap.set(node, _num);
510 void discover(const Edge& edge) {
511 _predMap.set(_graph.target(edge), _graph.source(edge));
514 void examine(const Edge& edge) {
515 if (_graph.source(edge) == _graph.target(edge) &&
516 _graph.direction(edge)) {
520 if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
523 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
524 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
528 void backtrack(const Edge& edge) {
529 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
530 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
532 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
541 typename Graph::template NodeMap<int> _numMap;
542 typename Graph::template NodeMap<int> _retMap;
543 typename Graph::template NodeMap<Node> _predMap;
547 template <typename Graph, typename EdgeMap>
548 class BiNodeConnectedComponentsVisitor : public DfsVisitor<Graph> {
550 typedef typename Graph::Node Node;
551 typedef typename Graph::Edge Edge;
552 typedef typename Graph::UEdge UEdge;
554 BiNodeConnectedComponentsVisitor(const Graph& graph,
555 EdgeMap& compMap, int &compNum)
556 : _graph(graph), _compMap(compMap), _compNum(compNum),
557 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
559 void start(const Node& node) {
560 _predMap.set(node, INVALID);
563 void reach(const Node& node) {
564 _numMap.set(node, _num);
565 _retMap.set(node, _num);
569 void discover(const Edge& edge) {
570 Node target = _graph.target(edge);
571 _predMap.set(target, edge);
572 _edgeStack.push(edge);
575 void examine(const Edge& edge) {
576 Node source = _graph.source(edge);
577 Node target = _graph.target(edge);
578 if (source == target && _graph.direction(edge)) {
579 _compMap.set(edge, _compNum);
583 if (_numMap[target] < _numMap[source]) {
584 if (_predMap[source] != _graph.oppositeEdge(edge)) {
585 _edgeStack.push(edge);
588 if (_predMap[source] != INVALID &&
589 target == _graph.source(_predMap[source])) {
592 if (_retMap[source] > _numMap[target]) {
593 _retMap.set(source, _numMap[target]);
597 void backtrack(const Edge& edge) {
598 Node source = _graph.source(edge);
599 Node target = _graph.target(edge);
600 if (_retMap[source] > _retMap[target]) {
601 _retMap.set(source, _retMap[target]);
603 if (_numMap[source] <= _retMap[target]) {
604 while (_edgeStack.top() != edge) {
605 _compMap.set(_edgeStack.top(), _compNum);
608 _compMap.set(edge, _compNum);
619 typename Graph::template NodeMap<int> _numMap;
620 typename Graph::template NodeMap<int> _retMap;
621 typename Graph::template NodeMap<Edge> _predMap;
622 std::stack<UEdge> _edgeStack;
627 template <typename Graph, typename NodeMap>
628 class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Graph> {
630 typedef typename Graph::Node Node;
631 typedef typename Graph::Edge Edge;
632 typedef typename Graph::UEdge UEdge;
634 BiNodeConnectedCutNodesVisitor(const Graph& graph, NodeMap& cutMap,
636 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
637 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
639 void start(const Node& node) {
640 _predMap.set(node, INVALID);
644 void reach(const Node& node) {
645 _numMap.set(node, _num);
646 _retMap.set(node, _num);
650 void discover(const Edge& edge) {
651 _predMap.set(_graph.target(edge), _graph.source(edge));
654 void examine(const Edge& edge) {
655 if (_graph.source(edge) == _graph.target(edge) &&
656 _graph.direction(edge)) {
657 if (!_cutMap[_graph.source(edge)]) {
658 _cutMap.set(_graph.source(edge), true);
663 if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
664 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
665 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
669 void backtrack(const Edge& edge) {
670 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
671 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
673 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
674 if (_predMap[_graph.source(edge)] != INVALID) {
675 if (!_cutMap[_graph.source(edge)]) {
676 _cutMap.set(_graph.source(edge), true);
679 } else if (rootCut) {
680 if (!_cutMap[_graph.source(edge)]) {
681 _cutMap.set(_graph.source(edge), true);
695 typename Graph::template NodeMap<int> _numMap;
696 typename Graph::template NodeMap<int> _retMap;
697 typename Graph::template NodeMap<Node> _predMap;
698 std::stack<UEdge> _edgeStack;
705 template <typename UGraph>
706 int countBiNodeConnectedComponents(const UGraph& graph);
708 /// \ingroup graph_prop
710 /// \brief Checks the graph is bi-node-connected.
712 /// This function checks that the undirected graph is bi-node-connected
713 /// graph. The graph is bi-node-connected if any two undirected edge is
716 /// \param graph The graph.
717 /// \return %True when the graph bi-node-connected.
718 template <typename UGraph>
719 bool biNodeConnected(const UGraph& graph) {
720 return countBiNodeConnectedComponents(graph) == 1;
723 /// \ingroup graph_prop
725 /// \brief Count the biconnected components.
727 /// This function finds the bi-node-connected components in an undirected
728 /// graph. The biconnected components are the classes of an equivalence
729 /// relation on the undirected edges. Two undirected edge is in relationship
730 /// when they are on same circle.
732 /// \param graph The graph.
733 /// \return The number of components.
734 template <typename UGraph>
735 int countBiNodeConnectedComponents(const UGraph& graph) {
736 checkConcept<concepts::UGraph, UGraph>();
737 typedef typename UGraph::NodeIt NodeIt;
739 using namespace _topology_bits;
741 typedef CountBiNodeConnectedComponentsVisitor<UGraph> Visitor;
744 Visitor visitor(graph, compNum);
746 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
749 for (NodeIt it(graph); it != INVALID; ++it) {
750 if (!dfs.reached(it)) {
758 /// \ingroup graph_prop
760 /// \brief Find the bi-node-connected components.
762 /// This function finds the bi-node-connected components in an undirected
763 /// graph. The bi-node-connected components are the classes of an equivalence
764 /// relation on the undirected edges. Two undirected edge are in relationship
765 /// when they are on same circle.
767 /// \image html node_biconnected_components.png
768 /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
770 /// \param graph The graph.
771 /// \retval compMap A writable uedge map. The values will be set from 0
772 /// to the number of the biconnected components minus one. Each values
773 /// of the map will be set exactly once, the values of a certain component
774 /// will be set continuously.
775 /// \return The number of components.
777 template <typename UGraph, typename UEdgeMap>
778 int biNodeConnectedComponents(const UGraph& graph,
780 checkConcept<concepts::UGraph, UGraph>();
781 typedef typename UGraph::NodeIt NodeIt;
782 typedef typename UGraph::UEdge UEdge;
783 checkConcept<concepts::WriteMap<UEdge, int>, UEdgeMap>();
785 using namespace _topology_bits;
787 typedef BiNodeConnectedComponentsVisitor<UGraph, UEdgeMap> Visitor;
790 Visitor visitor(graph, compMap, compNum);
792 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
795 for (NodeIt it(graph); it != INVALID; ++it) {
796 if (!dfs.reached(it)) {
804 /// \ingroup graph_prop
806 /// \brief Find the bi-node-connected cut nodes.
808 /// This function finds the bi-node-connected cut nodes in an undirected
809 /// graph. The bi-node-connected components are the classes of an equivalence
810 /// relation on the undirected edges. Two undirected edges are in
811 /// relationship when they are on same circle. The biconnected components
812 /// are separted by nodes which are the cut nodes of the components.
814 /// \param graph The graph.
815 /// \retval cutMap A writable edge map. The values will be set true when
816 /// the node separate two or more components.
817 /// \return The number of the cut nodes.
818 template <typename UGraph, typename NodeMap>
819 int biNodeConnectedCutNodes(const UGraph& graph, NodeMap& cutMap) {
820 checkConcept<concepts::UGraph, UGraph>();
821 typedef typename UGraph::Node Node;
822 typedef typename UGraph::NodeIt NodeIt;
823 checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
825 using namespace _topology_bits;
827 typedef BiNodeConnectedCutNodesVisitor<UGraph, NodeMap> Visitor;
830 Visitor visitor(graph, cutMap, cutNum);
832 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
835 for (NodeIt it(graph); it != INVALID; ++it) {
836 if (!dfs.reached(it)) {
844 namespace _topology_bits {
846 template <typename Graph>
847 class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Graph> {
849 typedef typename Graph::Node Node;
850 typedef typename Graph::Edge Edge;
851 typedef typename Graph::UEdge UEdge;
853 CountBiEdgeConnectedComponentsVisitor(const Graph& graph, int &compNum)
854 : _graph(graph), _compNum(compNum),
855 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
857 void start(const Node& node) {
858 _predMap.set(node, INVALID);
861 void reach(const Node& node) {
862 _numMap.set(node, _num);
863 _retMap.set(node, _num);
867 void leave(const Node& node) {
868 if (_numMap[node] <= _retMap[node]) {
873 void discover(const Edge& edge) {
874 _predMap.set(_graph.target(edge), edge);
877 void examine(const Edge& edge) {
878 if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
881 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
882 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
886 void backtrack(const Edge& edge) {
887 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
888 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
896 typename Graph::template NodeMap<int> _numMap;
897 typename Graph::template NodeMap<int> _retMap;
898 typename Graph::template NodeMap<Edge> _predMap;
902 template <typename Graph, typename NodeMap>
903 class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Graph> {
905 typedef typename Graph::Node Node;
906 typedef typename Graph::Edge Edge;
907 typedef typename Graph::UEdge UEdge;
909 BiEdgeConnectedComponentsVisitor(const Graph& graph,
910 NodeMap& compMap, int &compNum)
911 : _graph(graph), _compMap(compMap), _compNum(compNum),
912 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
914 void start(const Node& node) {
915 _predMap.set(node, INVALID);
918 void reach(const Node& node) {
919 _numMap.set(node, _num);
920 _retMap.set(node, _num);
921 _nodeStack.push(node);
925 void leave(const Node& node) {
926 if (_numMap[node] <= _retMap[node]) {
927 while (_nodeStack.top() != node) {
928 _compMap.set(_nodeStack.top(), _compNum);
931 _compMap.set(node, _compNum);
937 void discover(const Edge& edge) {
938 _predMap.set(_graph.target(edge), edge);
941 void examine(const Edge& edge) {
942 if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
945 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
946 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
950 void backtrack(const Edge& edge) {
951 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
952 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
961 typename Graph::template NodeMap<int> _numMap;
962 typename Graph::template NodeMap<int> _retMap;
963 typename Graph::template NodeMap<Edge> _predMap;
964 std::stack<Node> _nodeStack;
969 template <typename Graph, typename EdgeMap>
970 class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Graph> {
972 typedef typename Graph::Node Node;
973 typedef typename Graph::Edge Edge;
974 typedef typename Graph::UEdge UEdge;
976 BiEdgeConnectedCutEdgesVisitor(const Graph& graph,
977 EdgeMap& cutMap, int &cutNum)
978 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
979 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
981 void start(const Node& node) {
982 _predMap[node] = INVALID;
985 void reach(const Node& node) {
986 _numMap.set(node, _num);
987 _retMap.set(node, _num);
991 void leave(const Node& node) {
992 if (_numMap[node] <= _retMap[node]) {
993 if (_predMap[node] != INVALID) {
994 _cutMap.set(_predMap[node], true);
1000 void discover(const Edge& edge) {
1001 _predMap.set(_graph.target(edge), edge);
1004 void examine(const Edge& edge) {
1005 if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
1008 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1009 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1013 void backtrack(const Edge& edge) {
1014 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1015 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1020 const Graph& _graph;
1024 typename Graph::template NodeMap<int> _numMap;
1025 typename Graph::template NodeMap<int> _retMap;
1026 typename Graph::template NodeMap<Edge> _predMap;
1031 template <typename UGraph>
1032 int countBiEdgeConnectedComponents(const UGraph& graph);
1034 /// \ingroup graph_prop
1036 /// \brief Checks that the graph is bi-edge-connected.
1038 /// This function checks that the graph is bi-edge-connected. The undirected
1039 /// graph is bi-edge-connected when any two nodes are connected with two
1040 /// edge-disjoint paths.
1042 /// \param graph The undirected graph.
1043 /// \return The number of components.
1044 template <typename UGraph>
1045 bool biEdgeConnected(const UGraph& graph) {
1046 return countBiEdgeConnectedComponents(graph) == 1;
1049 /// \ingroup graph_prop
1051 /// \brief Count the bi-edge-connected components.
1053 /// This function count the bi-edge-connected components in an undirected
1054 /// graph. The bi-edge-connected components are the classes of an equivalence
1055 /// relation on the nodes. Two nodes are in relationship when they are
1056 /// connected with at least two edge-disjoint paths.
1058 /// \param graph The undirected graph.
1059 /// \return The number of components.
1060 template <typename UGraph>
1061 int countBiEdgeConnectedComponents(const UGraph& graph) {
1062 checkConcept<concepts::UGraph, UGraph>();
1063 typedef typename UGraph::NodeIt NodeIt;
1065 using namespace _topology_bits;
1067 typedef CountBiEdgeConnectedComponentsVisitor<UGraph> Visitor;
1070 Visitor visitor(graph, compNum);
1072 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
1075 for (NodeIt it(graph); it != INVALID; ++it) {
1076 if (!dfs.reached(it)) {
1084 /// \ingroup graph_prop
1086 /// \brief Find the bi-edge-connected components.
1088 /// This function finds the bi-edge-connected components in an undirected
1089 /// graph. The bi-edge-connected components are the classes of an equivalence
1090 /// relation on the nodes. Two nodes are in relationship when they are
1091 /// connected at least two edge-disjoint paths.
1093 /// \image html edge_biconnected_components.png
1094 /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
1096 /// \param graph The graph.
1097 /// \retval compMap A writable node map. The values will be set from 0 to
1098 /// the number of the biconnected components minus one. Each values
1099 /// of the map will be set exactly once, the values of a certain component
1100 /// will be set continuously.
1101 /// \return The number of components.
1103 template <typename UGraph, typename NodeMap>
1104 int biEdgeConnectedComponents(const UGraph& graph, NodeMap& compMap) {
1105 checkConcept<concepts::UGraph, UGraph>();
1106 typedef typename UGraph::NodeIt NodeIt;
1107 typedef typename UGraph::Node Node;
1108 checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1110 using namespace _topology_bits;
1112 typedef BiEdgeConnectedComponentsVisitor<UGraph, NodeMap> Visitor;
1115 Visitor visitor(graph, compMap, compNum);
1117 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
1120 for (NodeIt it(graph); it != INVALID; ++it) {
1121 if (!dfs.reached(it)) {
1129 /// \ingroup graph_prop
1131 /// \brief Find the bi-edge-connected cut edges.
1133 /// This function finds the bi-edge-connected components in an undirected
1134 /// graph. The bi-edge-connected components are the classes of an equivalence
1135 /// relation on the nodes. Two nodes are in relationship when they are
1136 /// connected with at least two edge-disjoint paths. The bi-edge-connected
1137 /// components are separted by edges which are the cut edges of the
1140 /// \param graph The graph.
1141 /// \retval cutMap A writable node map. The values will be set true when the
1142 /// edge is a cut edge.
1143 /// \return The number of cut edges.
1144 template <typename UGraph, typename UEdgeMap>
1145 int biEdgeConnectedCutEdges(const UGraph& graph, UEdgeMap& cutMap) {
1146 checkConcept<concepts::UGraph, UGraph>();
1147 typedef typename UGraph::NodeIt NodeIt;
1148 typedef typename UGraph::UEdge UEdge;
1149 checkConcept<concepts::WriteMap<UEdge, bool>, UEdgeMap>();
1151 using namespace _topology_bits;
1153 typedef BiEdgeConnectedCutEdgesVisitor<UGraph, UEdgeMap> Visitor;
1156 Visitor visitor(graph, cutMap, cutNum);
1158 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
1161 for (NodeIt it(graph); it != INVALID; ++it) {
1162 if (!dfs.reached(it)) {
1171 namespace _topology_bits {
1173 template <typename Graph, typename IntNodeMap>
1174 class TopologicalSortVisitor : public DfsVisitor<Graph> {
1176 typedef typename Graph::Node Node;
1177 typedef typename Graph::Edge edge;
1179 TopologicalSortVisitor(IntNodeMap& order, int num)
1180 : _order(order), _num(num) {}
1182 void leave(const Node& node) {
1183 _order.set(node, --_num);
1193 /// \ingroup graph_prop
1195 /// \brief Sort the nodes of a DAG into topolgical order.
1197 /// Sort the nodes of a DAG into topolgical order.
1199 /// \param graph The graph. It should be directed and acyclic.
1200 /// \retval order A writable node map. The values will be set from 0 to
1201 /// the number of the nodes in the graph minus one. Each values of the map
1202 /// will be set exactly once, the values will be set descending order.
1204 /// \see checkedTopologicalSort
1206 template <typename Graph, typename NodeMap>
1207 void topologicalSort(const Graph& graph, NodeMap& order) {
1208 using namespace _topology_bits;
1210 checkConcept<concepts::Graph, Graph>();
1211 checkConcept<concepts::WriteMap<typename Graph::Node, int>, NodeMap>();
1213 typedef typename Graph::Node Node;
1214 typedef typename Graph::NodeIt NodeIt;
1215 typedef typename Graph::Edge Edge;
1217 TopologicalSortVisitor<Graph, NodeMap>
1218 visitor(order, countNodes(graph));
1220 DfsVisit<Graph, TopologicalSortVisitor<Graph, NodeMap> >
1221 dfs(graph, visitor);
1224 for (NodeIt it(graph); it != INVALID; ++it) {
1225 if (!dfs.reached(it)) {
1232 /// \ingroup graph_prop
1234 /// \brief Sort the nodes of a DAG into topolgical order.
1236 /// Sort the nodes of a DAG into topolgical order. It also checks
1237 /// that the given graph is DAG.
1239 /// \param graph The graph. It should be directed and acyclic.
1240 /// \retval order A readable - writable node map. The values will be set
1241 /// from 0 to the number of the nodes in the graph minus one. Each values
1242 /// of the map will be set exactly once, the values will be set descending
1244 /// \return %False when the graph is not DAG.
1246 /// \see topologicalSort
1248 template <typename Graph, typename NodeMap>
1249 bool checkedTopologicalSort(const Graph& graph, NodeMap& order) {
1250 using namespace _topology_bits;
1252 checkConcept<concepts::Graph, Graph>();
1253 checkConcept<concepts::ReadWriteMap<typename Graph::Node, int>, NodeMap>();
1255 typedef typename Graph::Node Node;
1256 typedef typename Graph::NodeIt NodeIt;
1257 typedef typename Graph::Edge Edge;
1259 order = constMap<Node, int, -1>();
1261 TopologicalSortVisitor<Graph, NodeMap>
1262 visitor(order, countNodes(graph));
1264 DfsVisit<Graph, TopologicalSortVisitor<Graph, NodeMap> >
1265 dfs(graph, visitor);
1268 for (NodeIt it(graph); it != INVALID; ++it) {
1269 if (!dfs.reached(it)) {
1271 while (!dfs.emptyQueue()) {
1272 Edge edge = dfs.nextEdge();
1273 Node target = graph.target(edge);
1274 if (dfs.reached(target) && order[target] == -1) {
1277 dfs.processNextEdge();
1284 /// \ingroup graph_prop
1286 /// \brief Check that the given directed graph is a DAG.
1288 /// Check that the given directed graph is a DAG. The DAG is
1289 /// an Directed Acyclic Graph.
1290 /// \return %False when the graph is not DAG.
1292 template <typename Graph>
1293 bool dag(const Graph& graph) {
1295 checkConcept<concepts::Graph, Graph>();
1297 typedef typename Graph::Node Node;
1298 typedef typename Graph::NodeIt NodeIt;
1299 typedef typename Graph::Edge Edge;
1301 typedef typename Graph::template NodeMap<bool> ProcessedMap;
1303 typename Dfs<Graph>::template DefProcessedMap<ProcessedMap>::
1306 ProcessedMap processed(graph);
1307 dfs.processedMap(processed);
1310 for (NodeIt it(graph); it != INVALID; ++it) {
1311 if (!dfs.reached(it)) {
1313 while (!dfs.emptyQueue()) {
1314 Edge edge = dfs.nextEdge();
1315 Node target = graph.target(edge);
1316 if (dfs.reached(target) && !processed[target]) {
1319 dfs.processNextEdge();
1326 /// \ingroup graph_prop
1328 /// \brief Check that the given undirected graph is acyclic.
1330 /// Check that the given undirected graph acyclic.
1331 /// \param graph The undirected graph.
1332 /// \return %True when there is no circle in the graph.
1334 template <typename UGraph>
1335 bool acyclic(const UGraph& graph) {
1336 checkConcept<concepts::UGraph, UGraph>();
1337 typedef typename UGraph::Node Node;
1338 typedef typename UGraph::NodeIt NodeIt;
1339 typedef typename UGraph::Edge Edge;
1340 Dfs<UGraph> dfs(graph);
1342 for (NodeIt it(graph); it != INVALID; ++it) {
1343 if (!dfs.reached(it)) {
1345 while (!dfs.emptyQueue()) {
1346 Edge edge = dfs.nextEdge();
1347 Node source = graph.source(edge);
1348 Node target = graph.target(edge);
1349 if (dfs.reached(target) &&
1350 dfs.predEdge(source) != graph.oppositeEdge(edge)) {
1353 dfs.processNextEdge();
1360 /// \ingroup graph_prop
1362 /// \brief Check that the given undirected graph is tree.
1364 /// Check that the given undirected graph is tree.
1365 /// \param graph The undirected graph.
1366 /// \return %True when the graph is acyclic and connected.
1367 template <typename UGraph>
1368 bool tree(const UGraph& graph) {
1369 checkConcept<concepts::UGraph, UGraph>();
1370 typedef typename UGraph::Node Node;
1371 typedef typename UGraph::NodeIt NodeIt;
1372 typedef typename UGraph::Edge Edge;
1373 Dfs<UGraph> dfs(graph);
1375 dfs.addSource(NodeIt(graph));
1376 while (!dfs.emptyQueue()) {
1377 Edge edge = dfs.nextEdge();
1378 Node source = graph.source(edge);
1379 Node target = graph.target(edge);
1380 if (dfs.reached(target) &&
1381 dfs.predEdge(source) != graph.oppositeEdge(edge)) {
1384 dfs.processNextEdge();
1386 for (NodeIt it(graph); it != INVALID; ++it) {
1387 if (!dfs.reached(it)) {
1394 namespace _topology_bits {
1396 template <typename Graph>
1397 class BipartiteVisitor : public BfsVisitor<Graph> {
1399 typedef typename Graph::Edge Edge;
1400 typedef typename Graph::Node Node;
1402 BipartiteVisitor(const Graph& graph, bool& bipartite)
1403 : _graph(graph), _part(graph), _bipartite(bipartite) {}
1405 void start(const Node& node) {
1408 void discover(const Edge& edge) {
1409 _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1411 void examine(const Edge& edge) {
1412 _bipartite = _bipartite &&
1413 _part[_graph.target(edge)] != _part[_graph.source(edge)];
1418 const Graph& _graph;
1419 typename Graph::template NodeMap<bool> _part;
1423 template <typename Graph, typename PartMap>
1424 class BipartitePartitionsVisitor : public BfsVisitor<Graph> {
1426 typedef typename Graph::Edge Edge;
1427 typedef typename Graph::Node Node;
1429 BipartitePartitionsVisitor(const Graph& graph,
1430 PartMap& part, bool& bipartite)
1431 : _graph(graph), _part(part), _bipartite(bipartite) {}
1433 void start(const Node& node) {
1434 _part.set(node, true);
1436 void discover(const Edge& edge) {
1437 _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1439 void examine(const Edge& edge) {
1440 _bipartite = _bipartite &&
1441 _part[_graph.target(edge)] != _part[_graph.source(edge)];
1446 const Graph& _graph;
1452 /// \ingroup graph_prop
1454 /// \brief Check if the given undirected graph is bipartite or not
1456 /// The function checks if the given undirected \c graph graph is bipartite
1457 /// or not. The \ref Bfs algorithm is used to calculate the result.
1458 /// \param graph The undirected graph.
1459 /// \return %True if \c graph is bipartite, %false otherwise.
1460 /// \sa bipartitePartitions
1462 /// \author Balazs Attila Mihaly
1463 template<typename UGraph>
1464 inline bool bipartite(const UGraph &graph){
1465 using namespace _topology_bits;
1467 checkConcept<concepts::UGraph, UGraph>();
1469 typedef typename UGraph::NodeIt NodeIt;
1470 typedef typename UGraph::EdgeIt EdgeIt;
1472 bool bipartite = true;
1474 BipartiteVisitor<UGraph>
1475 visitor(graph, bipartite);
1476 BfsVisit<UGraph, BipartiteVisitor<UGraph> >
1477 bfs(graph, visitor);
1479 for(NodeIt it(graph); it != INVALID; ++it) {
1480 if(!bfs.reached(it)){
1482 while (!bfs.emptyQueue()) {
1483 bfs.processNextNode();
1484 if (!bipartite) return false;
1491 /// \ingroup graph_prop
1493 /// \brief Check if the given undirected graph is bipartite or not
1495 /// The function checks if the given undirected graph is bipartite
1496 /// or not. The \ref Bfs algorithm is used to calculate the result.
1497 /// During the execution, the \c partMap will be set as the two
1498 /// partitions of the graph.
1499 /// \param graph The undirected graph.
1500 /// \retval partMap A writable bool map of nodes. It will be set as the
1501 /// two partitions of the graph.
1502 /// \return %True if \c graph is bipartite, %false otherwise.
1504 /// \author Balazs Attila Mihaly
1506 /// \image html bipartite_partitions.png
1507 /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
1508 template<typename UGraph, typename NodeMap>
1509 inline bool bipartitePartitions(const UGraph &graph, NodeMap &partMap){
1510 using namespace _topology_bits;
1512 checkConcept<concepts::UGraph, UGraph>();
1514 typedef typename UGraph::Node Node;
1515 typedef typename UGraph::NodeIt NodeIt;
1516 typedef typename UGraph::EdgeIt EdgeIt;
1518 bool bipartite = true;
1520 BipartitePartitionsVisitor<UGraph, NodeMap>
1521 visitor(graph, partMap, bipartite);
1522 BfsVisit<UGraph, BipartitePartitionsVisitor<UGraph, NodeMap> >
1523 bfs(graph, visitor);
1525 for(NodeIt it(graph); it != INVALID; ++it) {
1526 if(!bfs.reached(it)){
1528 while (!bfs.emptyQueue()) {
1529 bfs.processNextNode();
1530 if (!bipartite) return false;
1537 /// \brief Returns true when there is not loop edge in the graph.
1539 /// Returns true when there is not loop edge in the graph.
1540 template <typename Graph>
1541 bool loopFree(const Graph& graph) {
1542 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
1543 if (graph.source(it) == graph.target(it)) return false;
1548 /// \brief Returns true when there is not parallel edges in the graph.
1550 /// Returns true when there is not parallel edges in the graph.
1551 template <typename Graph>
1552 bool parallelFree(const Graph& graph) {
1553 typename Graph::template NodeMap<bool> reached(graph, false);
1554 for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1555 for (typename Graph::OutEdgeIt e(graph, n); e != INVALID; ++e) {
1556 if (reached[graph.target(e)]) return false;
1557 reached.set(graph.target(e), true);
1559 for (typename Graph::OutEdgeIt e(graph, n); e != INVALID; ++e) {
1560 reached.set(graph.target(e), false);
1566 /// \brief Returns true when there is not loop edge and parallel
1567 /// edges in the graph.
1569 /// Returns true when there is not loop edge and parallel edges in
1571 template <typename Graph>
1572 bool simpleGraph(const Graph& graph) {
1573 typename Graph::template NodeMap<bool> reached(graph, false);
1574 for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1575 reached.set(n, true);
1576 for (typename Graph::OutEdgeIt e(graph, n); e != INVALID; ++e) {
1577 if (reached[graph.target(e)]) return false;
1578 reached.set(graph.target(e), true);
1580 for (typename Graph::OutEdgeIt e(graph, n); e != INVALID; ++e) {
1581 reached.set(graph.target(e), false);
1583 reached.set(n, false);
1590 #endif //LEMON_TOPOLOGY_H