# HG changeset patch
# User Gabor Gevay <ggab90@gmail.com>
# Date 1390004235 -3600
# Sat Jan 18 01:17:15 2014 +0100
# Node ID 7111be01ce588ac18d555c061a7b551ba470ab39
# Parent 15af6cbd77513ccf5ebcff573c1275858c6dd166
STL style iterators for bipartite graphs.
diff --git a/contrib/stlit_test/stlit_test.cc b/contrib/stlit_test/stlit_test.cc
|
a
|
b
|
|
| 3 | 3 | |
| 4 | 4 | |
| 5 | 5 | #include <iostream> |
| | 6 | #include <lemon/bits/stl_iterators.h> |
| 6 | 7 | #include <lemon/list_graph.h> |
| 7 | | #include <lemon/bits/stl_iterators.h> |
| | 8 | #include <lemon/smart_graph.h> |
| 8 | 9 | |
| 9 | 10 | |
| 10 | 11 | using namespace std; |
| … |
… |
|
| 72 | 73 | vector<ListDigraph::Node> v1(n); |
| 73 | 74 | copy(g.nodes().begin(), g.nodes().end(), v1.begin()); |
| 74 | 75 | |
| 75 | | vector<ListDigraph::Node> v(g.nodes().begin(), g.nodes().end()); |
| 76 | | g.addArc(v[0],v[1]); |
| 77 | | g.addArc(v[0],v[2]); |
| | 76 | vector<ListDigraph::Node> vect(g.nodes().begin(), g.nodes().end()); |
| | 77 | g.addArc(vect[0],vect[1]); |
| | 78 | g.addArc(vect[0],vect[2]); |
| 78 | 79 | |
| 79 | | for(auto e: g.outArcs(v[0])) |
| | 80 | for(auto e: g.outArcs(vect[0])) |
| 80 | 81 | cout<<g.id(g.target(e))<<endl; |
| 81 | 82 | |
| 82 | 83 | cout<<endl; |
| … |
… |
|
| 94 | 95 | st1->operator==(st2); |
| 95 | 96 | |
| 96 | 97 | |
| 97 | | ListGraph g2; |
| | 98 | //ListGraph g2; |
| | 99 | SmartGraph g2; |
| | 100 | g2.addEdge(g2.addNode(), g2.addNode()); |
| 98 | 101 | for(auto u: g2.nodes()) |
| 99 | 102 | cout<<g2.id(u)<<endl; |
| 100 | 103 | for(auto a: g2.outArcs(*g2.nodes().begin())) |
| 101 | 104 | cout<<g2.id(g2.target(a))<<endl; |
| 102 | 105 | |
| | 106 | cout<<endl; |
| | 107 | |
| | 108 | //ListBpGraph g3; |
| | 109 | SmartBpGraph g3; |
| | 110 | g3.addEdge(g3.addBlueNode(), g3.addRedNode()); |
| | 111 | for(auto u: g3.nodes()) { |
| | 112 | for(auto e: g3.incEdges(u)) |
| | 113 | cout<<g3.id(g3.v(e))<<endl; |
| | 114 | for(auto a: g3.outArcs(u)) |
| | 115 | cout<<g3.id(g3.target(a))<<endl; |
| | 116 | for(auto a: g3.inArcs(u)) |
| | 117 | cout<<g3.id(g3.target(a))<<endl; |
| | 118 | } |
| | 119 | for(auto e: g3.edges()) |
| | 120 | cout<<g3.id(g3.u(e))<<endl; |
| | 121 | for(auto a: g3.arcs()) |
| | 122 | cout<<g3.id(g3.target(a))<<endl; |
| | 123 | for(auto u: g3.redNodes()) |
| | 124 | cout<<g3.id(u)<<endl; |
| | 125 | for(auto u: g3.blueNodes()) |
| | 126 | cout<<g3.id(u)<<endl; |
| | 127 | |
| 103 | 128 | return 0; |
| 104 | 129 | } |
diff --git a/lemon/bits/graph_extender.h b/lemon/bits/graph_extender.h
|
a
|
b
|
|
| 947 | 947 | |
| 948 | 948 | }; |
| 949 | 949 | |
| | 950 | LemonRangeWrapper1<NodeIt, BpGraph> nodes() const { |
| | 951 | return LemonRangeWrapper1<NodeIt, BpGraph>(*this); |
| | 952 | } |
| | 953 | |
| | 954 | |
| 950 | 955 | class RedNodeIt : public RedNode { |
| 951 | 956 | const BpGraph* _graph; |
| 952 | 957 | public: |
| … |
… |
|
| 969 | 974 | |
| 970 | 975 | }; |
| 971 | 976 | |
| | 977 | LemonRangeWrapper1<RedNodeIt, BpGraph> redNodes() const { |
| | 978 | return LemonRangeWrapper1<RedNodeIt, BpGraph>(*this); |
| | 979 | } |
| | 980 | |
| | 981 | |
| 972 | 982 | class BlueNodeIt : public BlueNode { |
| 973 | 983 | const BpGraph* _graph; |
| 974 | 984 | public: |
| … |
… |
|
| 991 | 1001 | |
| 992 | 1002 | }; |
| 993 | 1003 | |
| | 1004 | LemonRangeWrapper1<BlueNodeIt, BpGraph> blueNodes() const { |
| | 1005 | return LemonRangeWrapper1<BlueNodeIt, BpGraph>(*this); |
| | 1006 | } |
| | 1007 | |
| | 1008 | |
| 994 | 1009 | |
| 995 | 1010 | class ArcIt : public Arc { |
| 996 | 1011 | const BpGraph* _graph; |
| … |
… |
|
| 1014 | 1029 | |
| 1015 | 1030 | }; |
| 1016 | 1031 | |
| | 1032 | LemonRangeWrapper1<ArcIt, BpGraph> arcs() const { |
| | 1033 | return LemonRangeWrapper1<ArcIt, BpGraph>(*this); |
| | 1034 | } |
| | 1035 | |
| 1017 | 1036 | |
| 1018 | 1037 | class OutArcIt : public Arc { |
| 1019 | 1038 | const BpGraph* _graph; |
| … |
… |
|
| 1038 | 1057 | |
| 1039 | 1058 | }; |
| 1040 | 1059 | |
| | 1060 | LemonRangeWrapper2<OutArcIt, BpGraph, Node> outArcs(const Node& u) const { |
| | 1061 | return LemonRangeWrapper2<OutArcIt, BpGraph, Node>(*this, u); |
| | 1062 | } |
| | 1063 | |
| 1041 | 1064 | |
| 1042 | 1065 | class InArcIt : public Arc { |
| 1043 | 1066 | const BpGraph* _graph; |
| … |
… |
|
| 1062 | 1085 | |
| 1063 | 1086 | }; |
| 1064 | 1087 | |
| | 1088 | LemonRangeWrapper2<InArcIt, BpGraph, Node> inArcs(const Node& u) const { |
| | 1089 | return LemonRangeWrapper2<InArcIt, BpGraph, Node>(*this, u); |
| | 1090 | } |
| | 1091 | |
| 1065 | 1092 | |
| 1066 | 1093 | class EdgeIt : public Parent::Edge { |
| 1067 | 1094 | const BpGraph* _graph; |
| … |
… |
|
| 1085 | 1112 | |
| 1086 | 1113 | }; |
| 1087 | 1114 | |
| | 1115 | LemonRangeWrapper1<EdgeIt, BpGraph> edges() const { |
| | 1116 | return LemonRangeWrapper1<EdgeIt, BpGraph>(*this); |
| | 1117 | } |
| | 1118 | |
| | 1119 | |
| 1088 | 1120 | class IncEdgeIt : public Parent::Edge { |
| 1089 | 1121 | friend class BpGraphExtender; |
| 1090 | 1122 | const BpGraph* _graph; |
| … |
… |
|
| 1110 | 1142 | } |
| 1111 | 1143 | }; |
| 1112 | 1144 | |
| | 1145 | LemonRangeWrapper2<IncEdgeIt, BpGraph, Node> incEdges(const Node& u) const { |
| | 1146 | return LemonRangeWrapper2<IncEdgeIt, BpGraph, Node>(*this, u); |
| | 1147 | } |
| | 1148 | |
| | 1149 | |
| 1113 | 1150 | // \brief Base node of the iterator |
| 1114 | 1151 | // |
| 1115 | 1152 | // Returns the base node (ie. the source in this case) of the iterator |
diff --git a/lemon/concepts/bpgraph.h b/lemon/concepts/bpgraph.h
|
a
|
b
|
|
| 221 | 221 | RedNodeIt& operator++() { return *this; } |
| 222 | 222 | }; |
| 223 | 223 | |
| | 224 | /// \brief Gets the collection of the red nodes of the graph. |
| | 225 | /// |
| | 226 | /// This function can be used for iterating on |
| | 227 | /// the red nodes of the graph. It returns a wrapped RedNodeIt, |
| | 228 | /// which looks like an STL container (by having begin() and end()) |
| | 229 | /// which you can use in range-based for loops, stl algorithms, etc. |
| | 230 | /// For example if g is a BpGraph, you can write: |
| | 231 | ///\code |
| | 232 | /// for(auto v: g.redNodes()) |
| | 233 | /// doSomething(v); |
| | 234 | ///\endcode |
| | 235 | LemonRangeWrapper1<RedNodeIt, BpGraph> redNodes() const { |
| | 236 | return LemonRangeWrapper1<RedNodeIt, BpGraph>(*this); |
| | 237 | } |
| | 238 | |
| | 239 | |
| 224 | 240 | /// Iterator class for the blue nodes. |
| 225 | 241 | |
| 226 | 242 | /// This iterator goes through each blue node of the graph. |
| … |
… |
|
| 264 | 280 | BlueNodeIt& operator++() { return *this; } |
| 265 | 281 | }; |
| 266 | 282 | |
| | 283 | /// \brief Gets the collection of the blue nodes of the graph. |
| | 284 | /// |
| | 285 | /// This function can be used for iterating on |
| | 286 | /// the blue nodes of the graph. It returns a wrapped BlueNodeIt, |
| | 287 | /// which looks like an STL container (by having begin() and end()) |
| | 288 | /// which you can use in range-based for loops, stl algorithms, etc. |
| | 289 | /// For example if g is a BpGraph, you can write: |
| | 290 | ///\code |
| | 291 | /// for(auto v: g.blueNodes()) |
| | 292 | /// doSomething(v); |
| | 293 | ///\endcode |
| | 294 | LemonRangeWrapper1<BlueNodeIt, BpGraph> blueNodes() const { |
| | 295 | return LemonRangeWrapper1<BlueNodeIt, BpGraph>(*this); |
| | 296 | } |
| | 297 | |
| | 298 | |
| 267 | 299 | /// Iterator class for the nodes. |
| 268 | 300 | |
| 269 | 301 | /// This iterator goes through each node of the graph. |
| … |
… |
|
| 307 | 339 | NodeIt& operator++() { return *this; } |
| 308 | 340 | }; |
| 309 | 341 | |
| | 342 | /// \brief Gets the collection of the nodes of the graph. |
| | 343 | /// |
| | 344 | /// This function can be used for iterating on |
| | 345 | /// the nodes of the graph. It returns a wrapped NodeIt, |
| | 346 | /// which looks like an STL container (by having begin() and end()) |
| | 347 | /// which you can use in range-based for loops, stl algorithms, etc. |
| | 348 | /// For example if g is a BpGraph, you can write: |
| | 349 | ///\code |
| | 350 | /// for(auto v: g.nodes()) |
| | 351 | /// doSomething(v); |
| | 352 | ///\endcode |
| | 353 | LemonRangeWrapper1<NodeIt, BpGraph> nodes() const { |
| | 354 | return LemonRangeWrapper1<NodeIt, BpGraph>(*this); |
| | 355 | } |
| | 356 | |
| | 357 | |
| 310 | 358 | |
| 311 | 359 | /// The edge type of the graph |
| 312 | 360 | |
| … |
… |
|
| 395 | 443 | EdgeIt& operator++() { return *this; } |
| 396 | 444 | }; |
| 397 | 445 | |
| | 446 | /// \brief Gets the collection of the edges of the graph. |
| | 447 | /// |
| | 448 | /// This function can be used for iterating on the |
| | 449 | /// edges of the graph. It returns a wrapped |
| | 450 | /// EdgeIt, which looks like an STL container |
| | 451 | /// (by having begin() and end()) which you can use in range-based |
| | 452 | /// for loops, stl algorithms, etc. |
| | 453 | /// For example if g is a BpGraph, you can write: |
| | 454 | ///\code |
| | 455 | /// for(auto e: g.edges()) |
| | 456 | /// doSomething(e); |
| | 457 | ///\endcode |
| | 458 | LemonRangeWrapper1<EdgeIt, BpGraph> edges() const { |
| | 459 | return LemonRangeWrapper1<EdgeIt, BpGraph>(*this); |
| | 460 | } |
| | 461 | |
| | 462 | |
| 398 | 463 | /// Iterator class for the incident edges of a node. |
| 399 | 464 | |
| 400 | 465 | /// This iterator goes trough the incident undirected edges |
| … |
… |
|
| 443 | 508 | IncEdgeIt& operator++() { return *this; } |
| 444 | 509 | }; |
| 445 | 510 | |
| | 511 | /// \brief Gets the collection of the incident edges |
| | 512 | /// of a certain node of the graph. |
| | 513 | /// |
| | 514 | /// This function can be used for iterating on the |
| | 515 | /// incident undirected edges of a certain node of the graph. |
| | 516 | /// It returns a wrapped |
| | 517 | /// IncEdgeIt, which looks like an STL container |
| | 518 | /// (by having begin() and end()) which you can use in range-based |
| | 519 | /// for loops, stl algorithms, etc. |
| | 520 | /// For example if g is a BpGraph and u is a Node, you can write: |
| | 521 | ///\code |
| | 522 | /// for(auto e: g.incEdges(u)) |
| | 523 | /// doSomething(e); |
| | 524 | ///\endcode |
| | 525 | LemonRangeWrapper2<IncEdgeIt, BpGraph, Node> incEdges(const Node& u) const { |
| | 526 | return LemonRangeWrapper2<IncEdgeIt, BpGraph, Node>(*this, u); |
| | 527 | } |
| | 528 | |
| | 529 | |
| 446 | 530 | /// The arc type of the graph |
| 447 | 531 | |
| 448 | 532 | /// This class identifies a directed arc of the graph. It also serves |
| … |
… |
|
| 539 | 623 | ArcIt& operator++() { return *this; } |
| 540 | 624 | }; |
| 541 | 625 | |
| | 626 | /// \brief Gets the collection of the directed arcs of the graph. |
| | 627 | /// |
| | 628 | /// This function can be used for iterating on the |
| | 629 | /// arcs of the graph. It returns a wrapped |
| | 630 | /// ArcIt, which looks like an STL container |
| | 631 | /// (by having begin() and end()) which you can use in range-based |
| | 632 | /// for loops, stl algorithms, etc. |
| | 633 | /// For example if g is a BpGraph you can write: |
| | 634 | ///\code |
| | 635 | /// for(auto a: g.arcs()) |
| | 636 | /// doSomething(a); |
| | 637 | ///\endcode |
| | 638 | LemonRangeWrapper1<ArcIt, BpGraph> arcs() const { |
| | 639 | return LemonRangeWrapper1<ArcIt, BpGraph>(*this); |
| | 640 | } |
| | 641 | |
| | 642 | |
| 542 | 643 | /// Iterator class for the outgoing arcs of a node. |
| 543 | 644 | |
| 544 | 645 | /// This iterator goes trough the \e outgoing directed arcs of a |
| … |
… |
|
| 587 | 688 | OutArcIt& operator++() { return *this; } |
| 588 | 689 | }; |
| 589 | 690 | |
| | 691 | /// \brief Gets the collection of the outgoing directed arcs of a |
| | 692 | /// certain node of the graph. |
| | 693 | /// |
| | 694 | /// This function can be used for iterating on the |
| | 695 | /// outgoing arcs of a certain node of the graph. It returns a wrapped |
| | 696 | /// OutArcIt, which looks like an STL container |
| | 697 | /// (by having begin() and end()) which you can use in range-based |
| | 698 | /// for loops, stl algorithms, etc. |
| | 699 | /// For example if g is a BpGraph and u is a Node, you can write: |
| | 700 | ///\code |
| | 701 | /// for(auto a: g.outArcs(u)) |
| | 702 | /// doSomething(a); |
| | 703 | ///\endcode |
| | 704 | LemonRangeWrapper2<OutArcIt, BpGraph, Node> outArcs(const Node& u) const { |
| | 705 | return LemonRangeWrapper2<OutArcIt, BpGraph, Node>(*this, u); |
| | 706 | } |
| | 707 | |
| | 708 | |
| 590 | 709 | /// Iterator class for the incoming arcs of a node. |
| 591 | 710 | |
| 592 | 711 | /// This iterator goes trough the \e incoming directed arcs of a |
| … |
… |
|
| 635 | 754 | InArcIt& operator++() { return *this; } |
| 636 | 755 | }; |
| 637 | 756 | |
| | 757 | /// \brief Gets the collection of the incoming directed arcs of a |
| | 758 | /// certain node of the graph. |
| | 759 | /// |
| | 760 | /// This function can be used for iterating on the |
| | 761 | /// incoming arcs of a certain node of the graph. It returns a wrapped |
| | 762 | /// InArcIt, which looks like an STL container |
| | 763 | /// (by having begin() and end()) which you can use in range-based |
| | 764 | /// for loops, stl algorithms, etc. |
| | 765 | /// For example if g is a BpGraph and u is a Node, you can write: |
| | 766 | ///\code |
| | 767 | /// for(auto a: g.inArcs(u)) |
| | 768 | /// doSomething(a); |
| | 769 | ///\endcode |
| | 770 | LemonRangeWrapper2<InArcIt, BpGraph, Node> inArcs(const Node& u) const { |
| | 771 | return LemonRangeWrapper2<InArcIt, BpGraph, Node>(*this, u); |
| | 772 | } |
| | 773 | |
| | 774 | |
| 638 | 775 | /// \brief Standard graph map type for the nodes. |
| 639 | 776 | /// |
| 640 | 777 | /// Standard graph map type for the nodes. |
diff --git a/lemon/list_graph.h b/lemon/list_graph.h
|
a
|
b
|
|
| 1617 | 1617 | int prev_out, next_out; |
| 1618 | 1618 | }; |
| 1619 | 1619 | |
| 1620 | | std::vector<NodeT> nodes; |
| | 1620 | std::vector<NodeT> _nodes; |
| 1621 | 1621 | |
| 1622 | 1622 | int first_node, first_red, first_blue; |
| 1623 | 1623 | int max_red, max_blue; |
| 1624 | 1624 | |
| 1625 | 1625 | int first_free_red, first_free_blue; |
| 1626 | 1626 | |
| 1627 | | std::vector<ArcT> arcs; |
| | 1627 | std::vector<ArcT> _arcs; |
| 1628 | 1628 | |
| 1629 | 1629 | int first_free_arc; |
| 1630 | 1630 | |
| … |
… |
|
| 1706 | 1706 | }; |
| 1707 | 1707 | |
| 1708 | 1708 | ListBpGraphBase() |
| 1709 | | : nodes(), first_node(-1), |
| | 1709 | : _nodes(), first_node(-1), |
| 1710 | 1710 | first_red(-1), first_blue(-1), |
| 1711 | 1711 | max_red(-1), max_blue(-1), |
| 1712 | 1712 | first_free_red(-1), first_free_blue(-1), |
| 1713 | | arcs(), first_free_arc(-1) {} |
| 1714 | | |
| 1715 | | |
| 1716 | | bool red(Node n) const { return nodes[n.id].red; } |
| 1717 | | bool blue(Node n) const { return !nodes[n.id].red; } |
| | 1713 | _arcs(), first_free_arc(-1) {} |
| | 1714 | |
| | 1715 | |
| | 1716 | bool red(Node n) const { return _nodes[n.id].red; } |
| | 1717 | bool blue(Node n) const { return !_nodes[n.id].red; } |
| 1718 | 1718 | |
| 1719 | 1719 | static RedNode asRedNodeUnsafe(Node n) { return RedNode(n.id); } |
| 1720 | 1720 | static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n.id); } |
| 1721 | 1721 | |
| 1722 | | int maxNodeId() const { return nodes.size()-1; } |
| | 1722 | int maxNodeId() const { return _nodes.size()-1; } |
| 1723 | 1723 | int maxRedId() const { return max_red; } |
| 1724 | 1724 | int maxBlueId() const { return max_blue; } |
| 1725 | | int maxEdgeId() const { return arcs.size() / 2 - 1; } |
| 1726 | | int maxArcId() const { return arcs.size()-1; } |
| 1727 | | |
| 1728 | | Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); } |
| 1729 | | Node target(Arc e) const { return Node(arcs[e.id].target); } |
| | 1725 | int maxEdgeId() const { return _arcs.size() / 2 - 1; } |
| | 1726 | int maxArcId() const { return _arcs.size()-1; } |
| | 1727 | |
| | 1728 | Node source(Arc e) const { return Node(_arcs[e.id ^ 1].target); } |
| | 1729 | Node target(Arc e) const { return Node(_arcs[e.id].target); } |
| 1730 | 1730 | |
| 1731 | 1731 | RedNode redNode(Edge e) const { |
| 1732 | | return RedNode(arcs[2 * e.id].target); |
| | 1732 | return RedNode(_arcs[2 * e.id].target); |
| 1733 | 1733 | } |
| 1734 | 1734 | BlueNode blueNode(Edge e) const { |
| 1735 | | return BlueNode(arcs[2 * e.id + 1].target); |
| | 1735 | return BlueNode(_arcs[2 * e.id + 1].target); |
| 1736 | 1736 | } |
| 1737 | 1737 | |
| 1738 | 1738 | static bool direction(Arc e) { |
| … |
… |
|
| 1748 | 1748 | } |
| 1749 | 1749 | |
| 1750 | 1750 | void next(Node& node) const { |
| 1751 | | node.id = nodes[node.id].next; |
| | 1751 | node.id = _nodes[node.id].next; |
| 1752 | 1752 | } |
| 1753 | 1753 | |
| 1754 | 1754 | void first(RedNode& node) const { |
| … |
… |
|
| 1756 | 1756 | } |
| 1757 | 1757 | |
| 1758 | 1758 | void next(RedNode& node) const { |
| 1759 | | node.id = nodes[node.id].partition_next; |
| | 1759 | node.id = _nodes[node.id].partition_next; |
| 1760 | 1760 | } |
| 1761 | 1761 | |
| 1762 | 1762 | void first(BlueNode& node) const { |
| … |
… |
|
| 1764 | 1764 | } |
| 1765 | 1765 | |
| 1766 | 1766 | void next(BlueNode& node) const { |
| 1767 | | node.id = nodes[node.id].partition_next; |
| | 1767 | node.id = _nodes[node.id].partition_next; |
| 1768 | 1768 | } |
| 1769 | 1769 | |
| 1770 | 1770 | void first(Arc& e) const { |
| 1771 | 1771 | int n = first_node; |
| 1772 | | while (n != -1 && nodes[n].first_out == -1) { |
| 1773 | | n = nodes[n].next; |
| | 1772 | while (n != -1 && _nodes[n].first_out == -1) { |
| | 1773 | n = _nodes[n].next; |
| 1774 | 1774 | } |
| 1775 | | e.id = (n == -1) ? -1 : nodes[n].first_out; |
| | 1775 | e.id = (n == -1) ? -1 : _nodes[n].first_out; |
| 1776 | 1776 | } |
| 1777 | 1777 | |
| 1778 | 1778 | void next(Arc& e) const { |
| 1779 | | if (arcs[e.id].next_out != -1) { |
| 1780 | | e.id = arcs[e.id].next_out; |
| | 1779 | if (_arcs[e.id].next_out != -1) { |
| | 1780 | e.id = _arcs[e.id].next_out; |
| 1781 | 1781 | } else { |
| 1782 | | int n = nodes[arcs[e.id ^ 1].target].next; |
| 1783 | | while(n != -1 && nodes[n].first_out == -1) { |
| 1784 | | n = nodes[n].next; |
| | 1782 | int n = _nodes[_arcs[e.id ^ 1].target].next; |
| | 1783 | while(n != -1 && _nodes[n].first_out == -1) { |
| | 1784 | n = _nodes[n].next; |
| 1785 | 1785 | } |
| 1786 | | e.id = (n == -1) ? -1 : nodes[n].first_out; |
| | 1786 | e.id = (n == -1) ? -1 : _nodes[n].first_out; |
| 1787 | 1787 | } |
| 1788 | 1788 | } |
| 1789 | 1789 | |
| 1790 | 1790 | void first(Edge& e) const { |
| 1791 | 1791 | int n = first_node; |
| 1792 | 1792 | while (n != -1) { |
| 1793 | | e.id = nodes[n].first_out; |
| | 1793 | e.id = _nodes[n].first_out; |
| 1794 | 1794 | while ((e.id & 1) != 1) { |
| 1795 | | e.id = arcs[e.id].next_out; |
| | 1795 | e.id = _arcs[e.id].next_out; |
| 1796 | 1796 | } |
| 1797 | 1797 | if (e.id != -1) { |
| 1798 | 1798 | e.id /= 2; |
| 1799 | 1799 | return; |
| 1800 | 1800 | } |
| 1801 | | n = nodes[n].next; |
| | 1801 | n = _nodes[n].next; |
| 1802 | 1802 | } |
| 1803 | 1803 | e.id = -1; |
| 1804 | 1804 | } |
| 1805 | 1805 | |
| 1806 | 1806 | void next(Edge& e) const { |
| 1807 | | int n = arcs[e.id * 2].target; |
| 1808 | | e.id = arcs[(e.id * 2) | 1].next_out; |
| | 1807 | int n = _arcs[e.id * 2].target; |
| | 1808 | e.id = _arcs[(e.id * 2) | 1].next_out; |
| 1809 | 1809 | while ((e.id & 1) != 1) { |
| 1810 | | e.id = arcs[e.id].next_out; |
| | 1810 | e.id = _arcs[e.id].next_out; |
| 1811 | 1811 | } |
| 1812 | 1812 | if (e.id != -1) { |
| 1813 | 1813 | e.id /= 2; |
| 1814 | 1814 | return; |
| 1815 | 1815 | } |
| 1816 | | n = nodes[n].next; |
| | 1816 | n = _nodes[n].next; |
| 1817 | 1817 | while (n != -1) { |
| 1818 | | e.id = nodes[n].first_out; |
| | 1818 | e.id = _nodes[n].first_out; |
| 1819 | 1819 | while ((e.id & 1) != 1) { |
| 1820 | | e.id = arcs[e.id].next_out; |
| | 1820 | e.id = _arcs[e.id].next_out; |
| 1821 | 1821 | } |
| 1822 | 1822 | if (e.id != -1) { |
| 1823 | 1823 | e.id /= 2; |
| 1824 | 1824 | return; |
| 1825 | 1825 | } |
| 1826 | | n = nodes[n].next; |
| | 1826 | n = _nodes[n].next; |
| 1827 | 1827 | } |
| 1828 | 1828 | e.id = -1; |
| 1829 | 1829 | } |
| 1830 | 1830 | |
| 1831 | 1831 | void firstOut(Arc &e, const Node& v) const { |
| 1832 | | e.id = nodes[v.id].first_out; |
| | 1832 | e.id = _nodes[v.id].first_out; |
| 1833 | 1833 | } |
| 1834 | 1834 | void nextOut(Arc &e) const { |
| 1835 | | e.id = arcs[e.id].next_out; |
| | 1835 | e.id = _arcs[e.id].next_out; |
| 1836 | 1836 | } |
| 1837 | 1837 | |
| 1838 | 1838 | void firstIn(Arc &e, const Node& v) const { |
| 1839 | | e.id = ((nodes[v.id].first_out) ^ 1); |
| | 1839 | e.id = ((_nodes[v.id].first_out) ^ 1); |
| 1840 | 1840 | if (e.id == -2) e.id = -1; |
| 1841 | 1841 | } |
| 1842 | 1842 | void nextIn(Arc &e) const { |
| 1843 | | e.id = ((arcs[e.id ^ 1].next_out) ^ 1); |
| | 1843 | e.id = ((_arcs[e.id ^ 1].next_out) ^ 1); |
| 1844 | 1844 | if (e.id == -2) e.id = -1; |
| 1845 | 1845 | } |
| 1846 | 1846 | |
| 1847 | 1847 | void firstInc(Edge &e, bool& d, const Node& v) const { |
| 1848 | | int a = nodes[v.id].first_out; |
| | 1848 | int a = _nodes[v.id].first_out; |
| 1849 | 1849 | if (a != -1 ) { |
| 1850 | 1850 | e.id = a / 2; |
| 1851 | 1851 | d = ((a & 1) == 1); |
| … |
… |
|
| 1855 | 1855 | } |
| 1856 | 1856 | } |
| 1857 | 1857 | void nextInc(Edge &e, bool& d) const { |
| 1858 | | int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out); |
| | 1858 | int a = (_arcs[(e.id * 2) | (d ? 1 : 0)].next_out); |
| 1859 | 1859 | if (a != -1 ) { |
| 1860 | 1860 | e.id = a / 2; |
| 1861 | 1861 | d = ((a & 1) == 1); |
| … |
… |
|
| 1866 | 1866 | } |
| 1867 | 1867 | |
| 1868 | 1868 | static int id(Node v) { return v.id; } |
| 1869 | | int id(RedNode v) const { return nodes[v.id].partition_index; } |
| 1870 | | int id(BlueNode v) const { return nodes[v.id].partition_index; } |
| | 1869 | int id(RedNode v) const { return _nodes[v.id].partition_index; } |
| | 1870 | int id(BlueNode v) const { return _nodes[v.id].partition_index; } |
| 1871 | 1871 | static int id(Arc e) { return e.id; } |
| 1872 | 1872 | static int id(Edge e) { return e.id; } |
| 1873 | 1873 | |
| … |
… |
|
| 1876 | 1876 | static Edge edgeFromId(int id) { return Edge(id);} |
| 1877 | 1877 | |
| 1878 | 1878 | bool valid(Node n) const { |
| 1879 | | return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
| 1880 | | nodes[n.id].prev != -2; |
| | 1879 | return n.id >= 0 && n.id < static_cast<int>(_nodes.size()) && |
| | 1880 | _nodes[n.id].prev != -2; |
| 1881 | 1881 | } |
| 1882 | 1882 | |
| 1883 | 1883 | bool valid(Arc a) const { |
| 1884 | | return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
| 1885 | | arcs[a.id].prev_out != -2; |
| | 1884 | return a.id >= 0 && a.id < static_cast<int>(_arcs.size()) && |
| | 1885 | _arcs[a.id].prev_out != -2; |
| 1886 | 1886 | } |
| 1887 | 1887 | |
| 1888 | 1888 | bool valid(Edge e) const { |
| 1889 | | return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && |
| 1890 | | arcs[2 * e.id].prev_out != -2; |
| | 1889 | return e.id >= 0 && 2 * e.id < static_cast<int>(_arcs.size()) && |
| | 1890 | _arcs[2 * e.id].prev_out != -2; |
| 1891 | 1891 | } |
| 1892 | 1892 | |
| 1893 | 1893 | RedNode addRedNode() { |
| 1894 | 1894 | int n; |
| 1895 | 1895 | |
| 1896 | 1896 | if(first_free_red==-1) { |
| 1897 | | n = nodes.size(); |
| 1898 | | nodes.push_back(NodeT()); |
| 1899 | | nodes[n].partition_index = ++max_red; |
| 1900 | | nodes[n].red = true; |
| | 1897 | n = _nodes.size(); |
| | 1898 | _nodes.push_back(NodeT()); |
| | 1899 | _nodes[n].partition_index = ++max_red; |
| | 1900 | _nodes[n].red = true; |
| 1901 | 1901 | } else { |
| 1902 | 1902 | n = first_free_red; |
| 1903 | | first_free_red = nodes[n].next; |
| | 1903 | first_free_red = _nodes[n].next; |
| 1904 | 1904 | } |
| 1905 | 1905 | |
| 1906 | | nodes[n].next = first_node; |
| 1907 | | if (first_node != -1) nodes[first_node].prev = n; |
| | 1906 | _nodes[n].next = first_node; |
| | 1907 | if (first_node != -1) _nodes[first_node].prev = n; |
| 1908 | 1908 | first_node = n; |
| 1909 | | nodes[n].prev = -1; |
| 1910 | | |
| 1911 | | nodes[n].partition_next = first_red; |
| 1912 | | if (first_red != -1) nodes[first_red].partition_prev = n; |
| | 1909 | _nodes[n].prev = -1; |
| | 1910 | |
| | 1911 | _nodes[n].partition_next = first_red; |
| | 1912 | if (first_red != -1) _nodes[first_red].partition_prev = n; |
| 1913 | 1913 | first_red = n; |
| 1914 | | nodes[n].partition_prev = -1; |
| 1915 | | |
| 1916 | | nodes[n].first_out = -1; |
| | 1914 | _nodes[n].partition_prev = -1; |
| | 1915 | |
| | 1916 | _nodes[n].first_out = -1; |
| 1917 | 1917 | |
| 1918 | 1918 | return RedNode(n); |
| 1919 | 1919 | } |
| … |
… |
|
| 1922 | 1922 | int n; |
| 1923 | 1923 | |
| 1924 | 1924 | if(first_free_blue==-1) { |
| 1925 | | n = nodes.size(); |
| 1926 | | nodes.push_back(NodeT()); |
| 1927 | | nodes[n].partition_index = ++max_blue; |
| 1928 | | nodes[n].red = false; |
| | 1925 | n = _nodes.size(); |
| | 1926 | _nodes.push_back(NodeT()); |
| | 1927 | _nodes[n].partition_index = ++max_blue; |
| | 1928 | _nodes[n].red = false; |
| 1929 | 1929 | } else { |
| 1930 | 1930 | n = first_free_blue; |
| 1931 | | first_free_blue = nodes[n].next; |
| | 1931 | first_free_blue = _nodes[n].next; |
| 1932 | 1932 | } |
| 1933 | 1933 | |
| 1934 | | nodes[n].next = first_node; |
| 1935 | | if (first_node != -1) nodes[first_node].prev = n; |
| | 1934 | _nodes[n].next = first_node; |
| | 1935 | if (first_node != -1) _nodes[first_node].prev = n; |
| 1936 | 1936 | first_node = n; |
| 1937 | | nodes[n].prev = -1; |
| 1938 | | |
| 1939 | | nodes[n].partition_next = first_blue; |
| 1940 | | if (first_blue != -1) nodes[first_blue].partition_prev = n; |
| | 1937 | _nodes[n].prev = -1; |
| | 1938 | |
| | 1939 | _nodes[n].partition_next = first_blue; |
| | 1940 | if (first_blue != -1) _nodes[first_blue].partition_prev = n; |
| 1941 | 1941 | first_blue = n; |
| 1942 | | nodes[n].partition_prev = -1; |
| 1943 | | |
| 1944 | | nodes[n].first_out = -1; |
| | 1942 | _nodes[n].partition_prev = -1; |
| | 1943 | |
| | 1944 | _nodes[n].first_out = -1; |
| 1945 | 1945 | |
| 1946 | 1946 | return BlueNode(n); |
| 1947 | 1947 | } |
| … |
… |
|
| 1950 | 1950 | int n; |
| 1951 | 1951 | |
| 1952 | 1952 | if (first_free_arc == -1) { |
| 1953 | | n = arcs.size(); |
| 1954 | | arcs.push_back(ArcT()); |
| 1955 | | arcs.push_back(ArcT()); |
| | 1953 | n = _arcs.size(); |
| | 1954 | _arcs.push_back(ArcT()); |
| | 1955 | _arcs.push_back(ArcT()); |
| 1956 | 1956 | } else { |
| 1957 | 1957 | n = first_free_arc; |
| 1958 | | first_free_arc = arcs[n].next_out; |
| | 1958 | first_free_arc = _arcs[n].next_out; |
| 1959 | 1959 | } |
| 1960 | 1960 | |
| 1961 | | arcs[n].target = u.id; |
| 1962 | | arcs[n | 1].target = v.id; |
| 1963 | | |
| 1964 | | arcs[n].next_out = nodes[v.id].first_out; |
| 1965 | | if (nodes[v.id].first_out != -1) { |
| 1966 | | arcs[nodes[v.id].first_out].prev_out = n; |
| | 1961 | _arcs[n].target = u.id; |
| | 1962 | _arcs[n | 1].target = v.id; |
| | 1963 | |
| | 1964 | _arcs[n].next_out = _nodes[v.id].first_out; |
| | 1965 | if (_nodes[v.id].first_out != -1) { |
| | 1966 | _arcs[_nodes[v.id].first_out].prev_out = n; |
| 1967 | 1967 | } |
| 1968 | | arcs[n].prev_out = -1; |
| 1969 | | nodes[v.id].first_out = n; |
| 1970 | | |
| 1971 | | arcs[n | 1].next_out = nodes[u.id].first_out; |
| 1972 | | if (nodes[u.id].first_out != -1) { |
| 1973 | | arcs[nodes[u.id].first_out].prev_out = (n | 1); |
| | 1968 | _arcs[n].prev_out = -1; |
| | 1969 | _nodes[v.id].first_out = n; |
| | 1970 | |
| | 1971 | _arcs[n | 1].next_out = _nodes[u.id].first_out; |
| | 1972 | if (_nodes[u.id].first_out != -1) { |
| | 1973 | _arcs[_nodes[u.id].first_out].prev_out = (n | 1); |
| 1974 | 1974 | } |
| 1975 | | arcs[n | 1].prev_out = -1; |
| 1976 | | nodes[u.id].first_out = (n | 1); |
| | 1975 | _arcs[n | 1].prev_out = -1; |
| | 1976 | _nodes[u.id].first_out = (n | 1); |
| 1977 | 1977 | |
| 1978 | 1978 | return Edge(n / 2); |
| 1979 | 1979 | } |
| … |
… |
|
| 1981 | 1981 | void erase(const Node& node) { |
| 1982 | 1982 | int n = node.id; |
| 1983 | 1983 | |
| 1984 | | if(nodes[n].next != -1) { |
| 1985 | | nodes[nodes[n].next].prev = nodes[n].prev; |
| | 1984 | if(_nodes[n].next != -1) { |
| | 1985 | _nodes[_nodes[n].next].prev = _nodes[n].prev; |
| 1986 | 1986 | } |
| 1987 | 1987 | |
| 1988 | | if(nodes[n].prev != -1) { |
| 1989 | | nodes[nodes[n].prev].next = nodes[n].next; |
| | 1988 | if(_nodes[n].prev != -1) { |
| | 1989 | _nodes[_nodes[n].prev].next = _nodes[n].next; |
| 1990 | 1990 | } else { |
| 1991 | | first_node = nodes[n].next; |
| | 1991 | first_node = _nodes[n].next; |
| 1992 | 1992 | } |
| 1993 | 1993 | |
| 1994 | | if (nodes[n].partition_next != -1) { |
| 1995 | | nodes[nodes[n].partition_next].partition_prev = nodes[n].partition_prev; |
| | 1994 | if (_nodes[n].partition_next != -1) { |
| | 1995 | _nodes[_nodes[n].partition_next].partition_prev = _nodes[n].partition_prev; |
| 1996 | 1996 | } |
| 1997 | 1997 | |
| 1998 | | if (nodes[n].partition_prev != -1) { |
| 1999 | | nodes[nodes[n].partition_prev].partition_next = nodes[n].partition_next; |
| | 1998 | if (_nodes[n].partition_prev != -1) { |
| | 1999 | _nodes[_nodes[n].partition_prev].partition_next = _nodes[n].partition_next; |
| 2000 | 2000 | } else { |
| 2001 | | if (nodes[n].red) { |
| 2002 | | first_red = nodes[n].partition_next; |
| | 2001 | if (_nodes[n].red) { |
| | 2002 | first_red = _nodes[n].partition_next; |
| 2003 | 2003 | } else { |
| 2004 | | first_blue = nodes[n].partition_next; |
| | 2004 | first_blue = _nodes[n].partition_next; |
| 2005 | 2005 | } |
| 2006 | 2006 | } |
| 2007 | 2007 | |
| 2008 | | if (nodes[n].red) { |
| 2009 | | nodes[n].next = first_free_red; |
| | 2008 | if (_nodes[n].red) { |
| | 2009 | _nodes[n].next = first_free_red; |
| 2010 | 2010 | first_free_red = n; |
| 2011 | 2011 | } else { |
| 2012 | | nodes[n].next = first_free_blue; |
| | 2012 | _nodes[n].next = first_free_blue; |
| 2013 | 2013 | first_free_blue = n; |
| 2014 | 2014 | } |
| 2015 | | nodes[n].prev = -2; |
| | 2015 | _nodes[n].prev = -2; |
| 2016 | 2016 | } |
| 2017 | 2017 | |
| 2018 | 2018 | void erase(const Edge& edge) { |
| 2019 | 2019 | int n = edge.id * 2; |
| 2020 | 2020 | |
| 2021 | | if (arcs[n].next_out != -1) { |
| 2022 | | arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
| | 2021 | if (_arcs[n].next_out != -1) { |
| | 2022 | _arcs[_arcs[n].next_out].prev_out = _arcs[n].prev_out; |
| 2023 | 2023 | } |
| 2024 | 2024 | |
| 2025 | | if (arcs[n].prev_out != -1) { |
| 2026 | | arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
| | 2025 | if (_arcs[n].prev_out != -1) { |
| | 2026 | _arcs[_arcs[n].prev_out].next_out = _arcs[n].next_out; |
| 2027 | 2027 | } else { |
| 2028 | | nodes[arcs[n | 1].target].first_out = arcs[n].next_out; |
| | 2028 | _nodes[_arcs[n | 1].target].first_out = _arcs[n].next_out; |
| 2029 | 2029 | } |
| 2030 | 2030 | |
| 2031 | | if (arcs[n | 1].next_out != -1) { |
| 2032 | | arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; |
| | 2031 | if (_arcs[n | 1].next_out != -1) { |
| | 2032 | _arcs[_arcs[n | 1].next_out].prev_out = _arcs[n | 1].prev_out; |
| 2033 | 2033 | } |
| 2034 | 2034 | |
| 2035 | | if (arcs[n | 1].prev_out != -1) { |
| 2036 | | arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; |
| | 2035 | if (_arcs[n | 1].prev_out != -1) { |
| | 2036 | _arcs[_arcs[n | 1].prev_out].next_out = _arcs[n | 1].next_out; |
| 2037 | 2037 | } else { |
| 2038 | | nodes[arcs[n].target].first_out = arcs[n | 1].next_out; |
| | 2038 | _nodes[_arcs[n].target].first_out = _arcs[n | 1].next_out; |
| 2039 | 2039 | } |
| 2040 | 2040 | |
| 2041 | | arcs[n].next_out = first_free_arc; |
| | 2041 | _arcs[n].next_out = first_free_arc; |
| 2042 | 2042 | first_free_arc = n; |
| 2043 | | arcs[n].prev_out = -2; |
| 2044 | | arcs[n | 1].prev_out = -2; |
| | 2043 | _arcs[n].prev_out = -2; |
| | 2044 | _arcs[n | 1].prev_out = -2; |
| 2045 | 2045 | |
| 2046 | 2046 | } |
| 2047 | 2047 | |
| 2048 | 2048 | void clear() { |
| 2049 | | arcs.clear(); |
| 2050 | | nodes.clear(); |
| | 2049 | _arcs.clear(); |
| | 2050 | _nodes.clear(); |
| 2051 | 2051 | first_node = first_free_arc = first_red = first_blue = |
| 2052 | 2052 | max_red = max_blue = first_free_red = first_free_blue = -1; |
| 2053 | 2053 | } |
| … |
… |
|
| 2055 | 2055 | protected: |
| 2056 | 2056 | |
| 2057 | 2057 | void changeRed(Edge e, RedNode n) { |
| 2058 | | if(arcs[(2 * e.id) | 1].next_out != -1) { |
| 2059 | | arcs[arcs[(2 * e.id) | 1].next_out].prev_out = |
| 2060 | | arcs[(2 * e.id) | 1].prev_out; |
| | 2058 | if(_arcs[(2 * e.id) | 1].next_out != -1) { |
| | 2059 | _arcs[_arcs[(2 * e.id) | 1].next_out].prev_out = |
| | 2060 | _arcs[(2 * e.id) | 1].prev_out; |
| 2061 | 2061 | } |
| 2062 | | if(arcs[(2 * e.id) | 1].prev_out != -1) { |
| 2063 | | arcs[arcs[(2 * e.id) | 1].prev_out].next_out = |
| 2064 | | arcs[(2 * e.id) | 1].next_out; |
| | 2062 | if(_arcs[(2 * e.id) | 1].prev_out != -1) { |
| | 2063 | _arcs[_arcs[(2 * e.id) | 1].prev_out].next_out = |
| | 2064 | _arcs[(2 * e.id) | 1].next_out; |
| 2065 | 2065 | } else { |
| 2066 | | nodes[arcs[2 * e.id].target].first_out = |
| 2067 | | arcs[(2 * e.id) | 1].next_out; |
| | 2066 | _nodes[_arcs[2 * e.id].target].first_out = |
| | 2067 | _arcs[(2 * e.id) | 1].next_out; |
| 2068 | 2068 | } |
| 2069 | 2069 | |
| 2070 | | if (nodes[n.id].first_out != -1) { |
| 2071 | | arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1); |
| | 2070 | if (_nodes[n.id].first_out != -1) { |
| | 2071 | _arcs[_nodes[n.id].first_out].prev_out = ((2 * e.id) | 1); |
| 2072 | 2072 | } |
| 2073 | | arcs[2 * e.id].target = n.id; |
| 2074 | | arcs[(2 * e.id) | 1].prev_out = -1; |
| 2075 | | arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out; |
| 2076 | | nodes[n.id].first_out = ((2 * e.id) | 1); |
| | 2073 | _arcs[2 * e.id].target = n.id; |
| | 2074 | _arcs[(2 * e.id) | 1].prev_out = -1; |
| | 2075 | _arcs[(2 * e.id) | 1].next_out = _nodes[n.id].first_out; |
| | 2076 | _nodes[n.id].first_out = ((2 * e.id) | 1); |
| 2077 | 2077 | } |
| 2078 | 2078 | |
| 2079 | 2079 | void changeBlue(Edge e, BlueNode n) { |
| 2080 | | if(arcs[2 * e.id].next_out != -1) { |
| 2081 | | arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out; |
| | 2080 | if(_arcs[2 * e.id].next_out != -1) { |
| | 2081 | _arcs[_arcs[2 * e.id].next_out].prev_out = _arcs[2 * e.id].prev_out; |
| 2082 | 2082 | } |
| 2083 | | if(arcs[2 * e.id].prev_out != -1) { |
| 2084 | | arcs[arcs[2 * e.id].prev_out].next_out = |
| 2085 | | arcs[2 * e.id].next_out; |
| | 2083 | if(_arcs[2 * e.id].prev_out != -1) { |
| | 2084 | _arcs[_arcs[2 * e.id].prev_out].next_out = |
| | 2085 | _arcs[2 * e.id].next_out; |
| 2086 | 2086 | } else { |
| 2087 | | nodes[arcs[(2 * e.id) | 1].target].first_out = |
| 2088 | | arcs[2 * e.id].next_out; |
| | 2087 | _nodes[_arcs[(2 * e.id) | 1].target].first_out = |
| | 2088 | _arcs[2 * e.id].next_out; |
| 2089 | 2089 | } |
| 2090 | 2090 | |
| 2091 | | if (nodes[n.id].first_out != -1) { |
| 2092 | | arcs[nodes[n.id].first_out].prev_out = 2 * e.id; |
| | 2091 | if (_nodes[n.id].first_out != -1) { |
| | 2092 | _arcs[_nodes[n.id].first_out].prev_out = 2 * e.id; |
| 2093 | 2093 | } |
| 2094 | | arcs[(2 * e.id) | 1].target = n.id; |
| 2095 | | arcs[2 * e.id].prev_out = -1; |
| 2096 | | arcs[2 * e.id].next_out = nodes[n.id].first_out; |
| 2097 | | nodes[n.id].first_out = 2 * e.id; |
| | 2094 | _arcs[(2 * e.id) | 1].target = n.id; |
| | 2095 | _arcs[2 * e.id].prev_out = -1; |
| | 2096 | _arcs[2 * e.id].next_out = _nodes[n.id].first_out; |
| | 2097 | _nodes[n.id].first_out = 2 * e.id; |
| 2098 | 2098 | } |
| 2099 | 2099 | |
| 2100 | 2100 | }; |
| … |
… |
|
| 2249 | 2249 | /// then it is worth reserving space for this amount before starting |
| 2250 | 2250 | /// to build the graph. |
| 2251 | 2251 | /// \sa reserveEdge() |
| 2252 | | void reserveNode(int n) { nodes.reserve(n); }; |
| | 2252 | void reserveNode(int n) { _nodes.reserve(n); }; |
| 2253 | 2253 | |
| 2254 | 2254 | /// Reserve memory for edges. |
| 2255 | 2255 | |
| … |
… |
|
| 2259 | 2259 | /// then it is worth reserving space for this amount before starting |
| 2260 | 2260 | /// to build the graph. |
| 2261 | 2261 | /// \sa reserveNode() |
| 2262 | | void reserveEdge(int m) { arcs.reserve(2 * m); }; |
| | 2262 | void reserveEdge(int m) { _arcs.reserve(2 * m); }; |
| 2263 | 2263 | |
| 2264 | 2264 | /// \brief Class to make a snapshot of the graph and restore |
| 2265 | 2265 | /// it later. |
diff --git a/lemon/smart_graph.h b/lemon/smart_graph.h
|
a
|
b
|
|
| 825 | 825 | int next_out; |
| 826 | 826 | }; |
| 827 | 827 | |
| 828 | | std::vector<NodeT> nodes; |
| 829 | | std::vector<ArcT> arcs; |
| | 828 | std::vector<NodeT> _nodes; |
| | 829 | std::vector<ArcT> _arcs; |
| 830 | 830 | |
| 831 | 831 | int first_red, first_blue; |
| 832 | 832 | int max_red, max_blue; |
| … |
… |
|
| 915 | 915 | |
| 916 | 916 | |
| 917 | 917 | SmartBpGraphBase() |
| 918 | | : nodes(), arcs(), first_red(-1), first_blue(-1), |
| | 918 | : _nodes(), _arcs(), first_red(-1), first_blue(-1), |
| 919 | 919 | max_red(-1), max_blue(-1) {} |
| 920 | 920 | |
| 921 | 921 | typedef True NodeNumTag; |
| 922 | 922 | typedef True EdgeNumTag; |
| 923 | 923 | typedef True ArcNumTag; |
| 924 | 924 | |
| 925 | | int nodeNum() const { return nodes.size(); } |
| | 925 | int nodeNum() const { return _nodes.size(); } |
| 926 | 926 | int redNum() const { return max_red + 1; } |
| 927 | 927 | int blueNum() const { return max_blue + 1; } |
| 928 | | int edgeNum() const { return arcs.size() / 2; } |
| 929 | | int arcNum() const { return arcs.size(); } |
| | 928 | int edgeNum() const { return _arcs.size() / 2; } |
| | 929 | int arcNum() const { return _arcs.size(); } |
| 930 | 930 | |
| 931 | | int maxNodeId() const { return nodes.size()-1; } |
| | 931 | int maxNodeId() const { return _nodes.size()-1; } |
| 932 | 932 | int maxRedId() const { return max_red; } |
| 933 | 933 | int maxBlueId() const { return max_blue; } |
| 934 | | int maxEdgeId() const { return arcs.size() / 2 - 1; } |
| 935 | | int maxArcId() const { return arcs.size()-1; } |
| | 934 | int maxEdgeId() const { return _arcs.size() / 2 - 1; } |
| | 935 | int maxArcId() const { return _arcs.size()-1; } |
| 936 | 936 | |
| 937 | | bool red(Node n) const { return nodes[n._id].red; } |
| 938 | | bool blue(Node n) const { return !nodes[n._id].red; } |
| | 937 | bool red(Node n) const { return _nodes[n._id].red; } |
| | 938 | bool blue(Node n) const { return !_nodes[n._id].red; } |
| 939 | 939 | |
| 940 | 940 | static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); } |
| 941 | 941 | static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); } |
| 942 | 942 | |
| 943 | | Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); } |
| 944 | | Node target(Arc a) const { return Node(arcs[a._id].target); } |
| | 943 | Node source(Arc a) const { return Node(_arcs[a._id ^ 1].target); } |
| | 944 | Node target(Arc a) const { return Node(_arcs[a._id].target); } |
| 945 | 945 | |
| 946 | 946 | RedNode redNode(Edge e) const { |
| 947 | | return RedNode(arcs[2 * e._id].target); |
| | 947 | return RedNode(_arcs[2 * e._id].target); |
| 948 | 948 | } |
| 949 | 949 | BlueNode blueNode(Edge e) const { |
| 950 | | return BlueNode(arcs[2 * e._id + 1].target); |
| | 950 | return BlueNode(_arcs[2 * e._id + 1].target); |
| 951 | 951 | } |
| 952 | 952 | |
| 953 | 953 | static bool direction(Arc a) { |
| … |
… |
|
| 959 | 959 | } |
| 960 | 960 | |
| 961 | 961 | void first(Node& node) const { |
| 962 | | node._id = nodes.size() - 1; |
| | 962 | node._id = _nodes.size() - 1; |
| 963 | 963 | } |
| 964 | 964 | |
| 965 | 965 | static void next(Node& node) { |
| … |
… |
|
| 971 | 971 | } |
| 972 | 972 | |
| 973 | 973 | void next(RedNode& node) const { |
| 974 | | node._id = nodes[node._id].partition_next; |
| | 974 | node._id = _nodes[node._id].partition_next; |
| 975 | 975 | } |
| 976 | 976 | |
| 977 | 977 | void first(BlueNode& node) const { |
| … |
… |
|
| 979 | 979 | } |
| 980 | 980 | |
| 981 | 981 | void next(BlueNode& node) const { |
| 982 | | node._id = nodes[node._id].partition_next; |
| | 982 | node._id = _nodes[node._id].partition_next; |
| 983 | 983 | } |
| 984 | 984 | |
| 985 | 985 | void first(Arc& arc) const { |
| 986 | | arc._id = arcs.size() - 1; |
| | 986 | arc._id = _arcs.size() - 1; |
| 987 | 987 | } |
| 988 | 988 | |
| 989 | 989 | static void next(Arc& arc) { |
| … |
… |
|
| 991 | 991 | } |
| 992 | 992 | |
| 993 | 993 | void first(Edge& arc) const { |
| 994 | | arc._id = arcs.size() / 2 - 1; |
| | 994 | arc._id = _arcs.size() / 2 - 1; |
| 995 | 995 | } |
| 996 | 996 | |
| 997 | 997 | static void next(Edge& arc) { |
| … |
… |
|
| 999 | 999 | } |
| 1000 | 1000 | |
| 1001 | 1001 | void firstOut(Arc &arc, const Node& v) const { |
| 1002 | | arc._id = nodes[v._id].first_out; |
| | 1002 | arc._id = _nodes[v._id].first_out; |
| 1003 | 1003 | } |
| 1004 | 1004 | void nextOut(Arc &arc) const { |
| 1005 | | arc._id = arcs[arc._id].next_out; |
| | 1005 | arc._id = _arcs[arc._id].next_out; |
| 1006 | 1006 | } |
| 1007 | 1007 | |
| 1008 | 1008 | void firstIn(Arc &arc, const Node& v) const { |
| 1009 | | arc._id = ((nodes[v._id].first_out) ^ 1); |
| | 1009 | arc._id = ((_nodes[v._id].first_out) ^ 1); |
| 1010 | 1010 | if (arc._id == -2) arc._id = -1; |
| 1011 | 1011 | } |
| 1012 | 1012 | void nextIn(Arc &arc) const { |
| 1013 | | arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1); |
| | 1013 | arc._id = ((_arcs[arc._id ^ 1].next_out) ^ 1); |
| 1014 | 1014 | if (arc._id == -2) arc._id = -1; |
| 1015 | 1015 | } |
| 1016 | 1016 | |
| 1017 | 1017 | void firstInc(Edge &arc, bool& d, const Node& v) const { |
| 1018 | | int de = nodes[v._id].first_out; |
| | 1018 | int de = _nodes[v._id].first_out; |
| 1019 | 1019 | if (de != -1) { |
| 1020 | 1020 | arc._id = de / 2; |
| 1021 | 1021 | d = ((de & 1) == 1); |
| … |
… |
|
| 1025 | 1025 | } |
| 1026 | 1026 | } |
| 1027 | 1027 | void nextInc(Edge &arc, bool& d) const { |
| 1028 | | int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out); |
| | 1028 | int de = (_arcs[(arc._id * 2) | (d ? 1 : 0)].next_out); |
| 1029 | 1029 | if (de != -1) { |
| 1030 | 1030 | arc._id = de / 2; |
| 1031 | 1031 | d = ((de & 1) == 1); |
| … |
… |
|
| 1036 | 1036 | } |
| 1037 | 1037 | |
| 1038 | 1038 | static int id(Node v) { return v._id; } |
| 1039 | | int id(RedNode v) const { return nodes[v._id].partition_index; } |
| 1040 | | int id(BlueNode v) const { return nodes[v._id].partition_index; } |
| | 1039 | int id(RedNode v) const { return _nodes[v._id].partition_index; } |
| | 1040 | int id(BlueNode v) const { return _nodes[v._id].partition_index; } |
| 1041 | 1041 | static int id(Arc e) { return e._id; } |
| 1042 | 1042 | static int id(Edge e) { return e._id; } |
| 1043 | 1043 | |
| … |
… |
|
| 1046 | 1046 | static Edge edgeFromId(int id) { return Edge(id);} |
| 1047 | 1047 | |
| 1048 | 1048 | bool valid(Node n) const { |
| 1049 | | return n._id >= 0 && n._id < static_cast<int>(nodes.size()); |
| | 1049 | return n._id >= 0 && n._id < static_cast<int>(_nodes.size()); |
| 1050 | 1050 | } |
| 1051 | 1051 | bool valid(Arc a) const { |
| 1052 | | return a._id >= 0 && a._id < static_cast<int>(arcs.size()); |
| | 1052 | return a._id >= 0 && a._id < static_cast<int>(_arcs.size()); |
| 1053 | 1053 | } |
| 1054 | 1054 | bool valid(Edge e) const { |
| 1055 | | return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size()); |
| | 1055 | return e._id >= 0 && 2 * e._id < static_cast<int>(_arcs.size()); |
| 1056 | 1056 | } |
| 1057 | 1057 | |
| 1058 | 1058 | RedNode addRedNode() { |
| 1059 | | int n = nodes.size(); |
| 1060 | | nodes.push_back(NodeT()); |
| 1061 | | nodes[n].first_out = -1; |
| 1062 | | nodes[n].red = true; |
| 1063 | | nodes[n].partition_index = ++max_red; |
| 1064 | | nodes[n].partition_next = first_red; |
| | 1059 | int n = _nodes.size(); |
| | 1060 | _nodes.push_back(NodeT()); |
| | 1061 | _nodes[n].first_out = -1; |
| | 1062 | _nodes[n].red = true; |
| | 1063 | _nodes[n].partition_index = ++max_red; |
| | 1064 | _nodes[n].partition_next = first_red; |
| 1065 | 1065 | first_red = n; |
| 1066 | 1066 | |
| 1067 | 1067 | return RedNode(n); |
| 1068 | 1068 | } |
| 1069 | 1069 | |
| 1070 | 1070 | BlueNode addBlueNode() { |
| 1071 | | int n = nodes.size(); |
| 1072 | | nodes.push_back(NodeT()); |
| 1073 | | nodes[n].first_out = -1; |
| 1074 | | nodes[n].red = false; |
| 1075 | | nodes[n].partition_index = ++max_blue; |
| 1076 | | nodes[n].partition_next = first_blue; |
| | 1071 | int n = _nodes.size(); |
| | 1072 | _nodes.push_back(NodeT()); |
| | 1073 | _nodes[n].first_out = -1; |
| | 1074 | _nodes[n].red = false; |
| | 1075 | _nodes[n].partition_index = ++max_blue; |
| | 1076 | _nodes[n].partition_next = first_blue; |
| 1077 | 1077 | first_blue = n; |
| 1078 | 1078 | |
| 1079 | 1079 | return BlueNode(n); |
| 1080 | 1080 | } |
| 1081 | 1081 | |
| 1082 | 1082 | Edge addEdge(RedNode u, BlueNode v) { |
| 1083 | | int n = arcs.size(); |
| 1084 | | arcs.push_back(ArcT()); |
| 1085 | | arcs.push_back(ArcT()); |
| | 1083 | int n = _arcs.size(); |
| | 1084 | _arcs.push_back(ArcT()); |
| | 1085 | _arcs.push_back(ArcT()); |
| 1086 | 1086 | |
| 1087 | | arcs[n].target = u._id; |
| 1088 | | arcs[n | 1].target = v._id; |
| | 1087 | _arcs[n].target = u._id; |
| | 1088 | _arcs[n | 1].target = v._id; |
| 1089 | 1089 | |
| 1090 | | arcs[n].next_out = nodes[v._id].first_out; |
| 1091 | | nodes[v._id].first_out = n; |
| | 1090 | _arcs[n].next_out = _nodes[v._id].first_out; |
| | 1091 | _nodes[v._id].first_out = n; |
| 1092 | 1092 | |
| 1093 | | arcs[n | 1].next_out = nodes[u._id].first_out; |
| 1094 | | nodes[u._id].first_out = (n | 1); |
| | 1093 | _arcs[n | 1].next_out = _nodes[u._id].first_out; |
| | 1094 | _nodes[u._id].first_out = (n | 1); |
| 1095 | 1095 | |
| 1096 | 1096 | return Edge(n / 2); |
| 1097 | 1097 | } |
| 1098 | 1098 | |
| 1099 | 1099 | void clear() { |
| 1100 | | arcs.clear(); |
| 1101 | | nodes.clear(); |
| | 1100 | _arcs.clear(); |
| | 1101 | _nodes.clear(); |
| 1102 | 1102 | first_red = -1; |
| 1103 | 1103 | first_blue = -1; |
| 1104 | 1104 | max_blue = -1; |
| … |
… |
|
| 1213 | 1213 | /// then it is worth reserving space for this amount before starting |
| 1214 | 1214 | /// to build the graph. |
| 1215 | 1215 | /// \sa reserveEdge() |
| 1216 | | void reserveNode(int n) { nodes.reserve(n); }; |
| | 1216 | void reserveNode(int n) { _nodes.reserve(n); }; |
| 1217 | 1217 | |
| 1218 | 1218 | /// Reserve memory for edges. |
| 1219 | 1219 | |
| … |
… |
|
| 1223 | 1223 | /// then it is worth reserving space for this amount before starting |
| 1224 | 1224 | /// to build the graph. |
| 1225 | 1225 | /// \sa reserveNode() |
| 1226 | | void reserveEdge(int m) { arcs.reserve(2 * m); }; |
| | 1226 | void reserveEdge(int m) { _arcs.reserve(2 * m); }; |
| 1227 | 1227 | |
| 1228 | 1228 | public: |
| 1229 | 1229 | |
| … |
… |
|
| 1234 | 1234 | void saveSnapshot(Snapshot &s) |
| 1235 | 1235 | { |
| 1236 | 1236 | s._graph = this; |
| 1237 | | s.node_num = nodes.size(); |
| 1238 | | s.arc_num = arcs.size(); |
| | 1237 | s.node_num = _nodes.size(); |
| | 1238 | s.arc_num = _arcs.size(); |
| 1239 | 1239 | } |
| 1240 | 1240 | |
| 1241 | 1241 | void restoreSnapshot(const Snapshot &s) |
| 1242 | 1242 | { |
| 1243 | | while(s.arc_num<arcs.size()) { |
| 1244 | | int n=arcs.size()-1; |
| | 1243 | while(s.arc_num<_arcs.size()) { |
| | 1244 | int n=_arcs.size()-1; |
| 1245 | 1245 | Edge arc=edgeFromId(n/2); |
| 1246 | 1246 | Parent::notifier(Edge()).erase(arc); |
| 1247 | 1247 | std::vector<Arc> dir; |
| 1248 | 1248 | dir.push_back(arcFromId(n)); |
| 1249 | 1249 | dir.push_back(arcFromId(n-1)); |
| 1250 | 1250 | Parent::notifier(Arc()).erase(dir); |
| 1251 | | nodes[arcs[n-1].target].first_out=arcs[n].next_out; |
| 1252 | | nodes[arcs[n].target].first_out=arcs[n-1].next_out; |
| 1253 | | arcs.pop_back(); |
| 1254 | | arcs.pop_back(); |
| | 1251 | _nodes[_arcs[n-1].target].first_out=_arcs[n].next_out; |
| | 1252 | _nodes[_arcs[n].target].first_out=_arcs[n-1].next_out; |
| | 1253 | _arcs.pop_back(); |
| | 1254 | _arcs.pop_back(); |
| 1255 | 1255 | } |
| 1256 | | while(s.node_num<nodes.size()) { |
| 1257 | | int n=nodes.size()-1; |
| | 1256 | while(s.node_num<_nodes.size()) { |
| | 1257 | int n=_nodes.size()-1; |
| 1258 | 1258 | Node node = nodeFromId(n); |
| 1259 | 1259 | if (Parent::red(node)) { |
| 1260 | | first_red = nodes[n].partition_next; |
| | 1260 | first_red = _nodes[n].partition_next; |
| 1261 | 1261 | if (first_red != -1) { |
| 1262 | | max_red = nodes[first_red].partition_index; |
| | 1262 | max_red = _nodes[first_red].partition_index; |
| 1263 | 1263 | } else { |
| 1264 | 1264 | max_red = -1; |
| 1265 | 1265 | } |
| 1266 | 1266 | Parent::notifier(RedNode()).erase(asRedNodeUnsafe(node)); |
| 1267 | 1267 | } else { |
| 1268 | | first_blue = nodes[n].partition_next; |
| | 1268 | first_blue = _nodes[n].partition_next; |
| 1269 | 1269 | if (first_blue != -1) { |
| 1270 | | max_blue = nodes[first_blue].partition_index; |
| | 1270 | max_blue = _nodes[first_blue].partition_index; |
| 1271 | 1271 | } else { |
| 1272 | 1272 | max_blue = -1; |
| 1273 | 1273 | } |
| 1274 | 1274 | Parent::notifier(BlueNode()).erase(asBlueNodeUnsafe(node)); |
| 1275 | 1275 | } |
| 1276 | 1276 | Parent::notifier(Node()).erase(node); |
| 1277 | | nodes.pop_back(); |
| | 1277 | _nodes.pop_back(); |
| 1278 | 1278 | } |
| 1279 | 1279 | } |
| 1280 | 1280 | |