Changes in lemon/list_graph.h [73:c56b7389dc78:39:0a01d811071f] in lemon-1.0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/list_graph.h
r73 r39 17 17 */ 18 18 19 #ifndef LEMON_LIST_GRAPH_H20 #define LEMON_LIST_GRAPH_H21 22 ///\ingroup graphs23 ///\file24 ///\brief ListDigraph, ListGraph classes.25 26 #include <lemon/bits/graph_extender.h>27 28 #include <vector>29 #include <list>30 31 namespace lemon {32 33 class ListDigraphBase {34 35 protected:36 struct NodeT {37 int first_in, first_out;38 int prev, next;39 };40 41 struct ArcT {42 int target, source;43 int prev_in, prev_out;44 int next_in, next_out;45 };46 47 std::vector<NodeT> nodes;48 49 int first_node;50 51 int first_free_node;52 53 std::vector<ArcT> arcs;54 55 int first_free_arc;56 57 public:58 59 typedef ListDigraphBase Digraph;60 61 class Node {62 friend class ListDigraphBase;63 protected:64 65 int id;66 explicit Node(int pid) { id = pid;}67 68 public:69 Node() {}70 Node (Invalid) { id = -1; }71 bool operator==(const Node& node) const {return id == node.id;}72 bool operator!=(const Node& node) const {return id != node.id;}73 bool operator<(const Node& node) const {return id < node.id;}74 };75 76 class Arc {77 friend class ListDigraphBase;78 protected:79 80 int id;81 explicit Arc(int pid) { id = pid;}82 83 public:84 Arc() {}85 Arc (Invalid) { id = -1; }86 bool operator==(const Arc& arc) const {return id == arc.id;}87 bool operator!=(const Arc& arc) const {return id != arc.id;}88 bool operator<(const Arc& arc) const {return id < arc.id;}89 };90 91 92 93 ListDigraphBase()94 : nodes(), first_node(-1),95 first_free_node(-1), arcs(), first_free_arc(-1) {}96 97 98 int maxNodeId() const { return nodes.size()-1; }99 int maxArcId() const { return arcs.size()-1; }100 101 Node source(Arc e) const { return Node(arcs[e.id].source); }102 Node target(Arc e) const { return Node(arcs[e.id].target); }103 104 105 void first(Node& node) const {106 node.id = first_node;107 }108 109 void next(Node& node) const {110 node.id = nodes[node.id].next;111 }112 113 114 void first(Arc& arc) const {115 int n;116 for(n = first_node;117 n!=-1 && nodes[n].first_in == -1;118 n = nodes[n].next);119 arc.id = (n == -1) ? -1 : nodes[n].first_in;120 }121 122 void next(Arc& arc) const {123 if (arcs[arc.id].next_in != -1) {124 arc.id = arcs[arc.id].next_in;125 } else {126 int n;127 for(n = nodes[arcs[arc.id].target].next;128 n!=-1 && nodes[n].first_in == -1;129 n = nodes[n].next);130 arc.id = (n == -1) ? -1 : nodes[n].first_in;131 }132 }133 134 void firstOut(Arc &e, const Node& v) const {135 e.id = nodes[v.id].first_out;136 }137 void nextOut(Arc &e) const {138 e.id=arcs[e.id].next_out;139 }140 141 void firstIn(Arc &e, const Node& v) const {142 e.id = nodes[v.id].first_in;143 }144 void nextIn(Arc &e) const {145 e.id=arcs[e.id].next_in;146 }147 148 149 static int id(Node v) { return v.id; }150 static int id(Arc e) { return e.id; }151 152 static Node nodeFromId(int id) { return Node(id);}153 static Arc arcFromId(int id) { return Arc(id);}154 155 Node addNode() {156 int n;157 158 if(first_free_node==-1) {159 n = nodes.size();160 nodes.push_back(NodeT());161 } else {162 n = first_free_node;163 first_free_node = nodes[n].next;164 }165 166 nodes[n].next = first_node;167 if(first_node != -1) nodes[first_node].prev = n;168 first_node = n;169 nodes[n].prev = -1;170 171 nodes[n].first_in = nodes[n].first_out = -1;172 173 return Node(n);174 }175 176 Arc addArc(Node u, Node v) {177 int n;178 179 if (first_free_arc == -1) {180 n = arcs.size();181 arcs.push_back(ArcT());182 } else {183 n = first_free_arc;184 first_free_arc = arcs[n].next_in;185 }186 187 arcs[n].source = u.id;188 arcs[n].target = v.id;189 190 arcs[n].next_out = nodes[u.id].first_out;191 if(nodes[u.id].first_out != -1) {192 arcs[nodes[u.id].first_out].prev_out = n;193 }194 195 arcs[n].next_in = nodes[v.id].first_in;196 if(nodes[v.id].first_in != -1) {197 arcs[nodes[v.id].first_in].prev_in = n;198 }199 200 arcs[n].prev_in = arcs[n].prev_out = -1;201 202 nodes[u.id].first_out = nodes[v.id].first_in = n;203 204 return Arc(n);205 }206 207 void erase(const Node& node) {208 int n = node.id;209 210 if(nodes[n].next != -1) {211 nodes[nodes[n].next].prev = nodes[n].prev;212 }213 214 if(nodes[n].prev != -1) {215 nodes[nodes[n].prev].next = nodes[n].next;216 } else {217 first_node = nodes[n].next;218 }219 220 nodes[n].next = first_free_node;221 first_free_node = n;222 223 }224 225 void erase(const Arc& arc) {226 int n = arc.id;227 228 if(arcs[n].next_in!=-1) {229 arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;230 }231 232 if(arcs[n].prev_in!=-1) {233 arcs[arcs[n].prev_in].next_in = arcs[n].next_in;234 } else {235 nodes[arcs[n].target].first_in = arcs[n].next_in;236 }237 238 239 if(arcs[n].next_out!=-1) {240 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;241 }242 243 if(arcs[n].prev_out!=-1) {244 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;245 } else {246 nodes[arcs[n].source].first_out = arcs[n].next_out;247 }248 249 arcs[n].next_in = first_free_arc;250 first_free_arc = n;251 252 }253 254 void clear() {255 arcs.clear();256 nodes.clear();257 first_node = first_free_node = first_free_arc = -1;258 }259 260 protected:261 void changeTarget(Arc e, Node n)262 {263 if(arcs[e.id].next_in != -1)264 arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;265 if(arcs[e.id].prev_in != -1)266 arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;267 else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;268 if (nodes[n.id].first_in != -1) {269 arcs[nodes[n.id].first_in].prev_in = e.id;270 }271 arcs[e.id].target = n.id;272 arcs[e.id].prev_in = -1;273 arcs[e.id].next_in = nodes[n.id].first_in;274 nodes[n.id].first_in = e.id;275 }276 void changeSource(Arc e, Node n)277 {278 if(arcs[e.id].next_out != -1)279 arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;280 if(arcs[e.id].prev_out != -1)281 arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;282 else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;283 if (nodes[n.id].first_out != -1) {284 arcs[nodes[n.id].first_out].prev_out = e.id;285 }286 arcs[e.id].source = n.id;287 arcs[e.id].prev_out = -1;288 arcs[e.id].next_out = nodes[n.id].first_out;289 nodes[n.id].first_out = e.id;290 }291 292 };293 294 typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;295 296 /// \addtogroup graphs297 /// @{298 299 ///A general directed graph structure.300 301 ///\ref ListDigraph is a simple and fast <em>directed graph</em>302 ///implementation based on static linked lists that are stored in303 ///\c std::vector structures.304 ///305 ///It conforms to the \ref concepts::Digraph "Digraph concept" and it306 ///also provides several useful additional functionalities.307 ///Most of the member functions and nested classes are documented308 ///only in the concept class.309 ///310 ///An important extra feature of this digraph implementation is that311 ///its maps are real \ref concepts::ReferenceMap "reference map"s.312 ///313 ///\sa concepts::Digraph314 315 class ListDigraph : public ExtendedListDigraphBase {316 private:317 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.318 319 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.320 ///321 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};322 ///\brief Assignment of ListDigraph to another one is \e not allowed.323 ///Use copyDigraph() instead.324 325 ///Assignment of ListDigraph to another one is \e not allowed.326 ///Use copyDigraph() instead.327 void operator=(const ListDigraph &) {}328 public:329 330 typedef ExtendedListDigraphBase Parent;331 332 /// Constructor333 334 /// Constructor.335 ///336 ListDigraph() {}337 338 ///Add a new node to the digraph.339 340 ///Add a new node to the digraph.341 ///\return the new node.342 Node addNode() { return Parent::addNode(); }343 344 ///Add a new arc to the digraph.345 346 ///Add a new arc to the digraph with source node \c s347 ///and target node \c t.348 ///\return the new arc.349 Arc addArc(const Node& s, const Node& t) {350 return Parent::addArc(s, t);351 }352 353 /// Change the target of \c e to \c n354 355 /// Change the target of \c e to \c n356 ///357 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing358 ///the changed arc remain valid. However <tt>InArcIt</tt>s are359 ///invalidated.360 ///361 ///\warning This functionality cannot be used together with the Snapshot362 ///feature.363 void changeTarget(Arc e, Node n) {364 Parent::changeTarget(e,n);365 }366 /// Change the source of \c e to \c n367 368 /// Change the source of \c e to \c n369 ///370 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing371 ///the changed arc remain valid. However <tt>OutArcIt</tt>s are372 ///invalidated.373 ///374 ///\warning This functionality cannot be used together with the Snapshot375 ///feature.376 void changeSource(Arc e, Node n) {377 Parent::changeSource(e,n);378 }379 380 /// Invert the direction of an arc.381 382 ///\note The <tt>ArcIt</tt>s referencing the changed arc remain383 ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are384 ///invalidated.385 ///386 ///\warning This functionality cannot be used together with the Snapshot387 ///feature.388 void reverseArc(Arc e) {389 Node t=target(e);390 changeTarget(e,source(e));391 changeSource(e,t);392 }393 394 /// Reserve memory for nodes.395 396 /// Using this function it is possible to avoid the superfluous memory397 /// allocation: if you know that the digraph you want to build will398 /// be very large (e.g. it will contain millions of nodes and/or arcs)399 /// then it is worth reserving space for this amount before starting400 /// to build the digraph.401 /// \sa reserveArc402 void reserveNode(int n) { nodes.reserve(n); };403 404 /// Reserve memory for arcs.405 406 /// Using this function it is possible to avoid the superfluous memory407 /// allocation: if you know that the digraph you want to build will408 /// be very large (e.g. it will contain millions of nodes and/or arcs)409 /// then it is worth reserving space for this amount before starting410 /// to build the digraph.411 /// \sa reserveNode412 void reserveArc(int m) { arcs.reserve(m); };413 414 ///Contract two nodes.415 416 ///This function contracts two nodes.417 ///Node \p b will be removed but instead of deleting418 ///incident arcs, they will be joined to \p a.419 ///The last parameter \p r controls whether to remove loops. \c true420 ///means that loops will be removed.421 ///422 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain423 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s424 ///may be invalidated.425 ///426 ///\warning This functionality cannot be used together with the Snapshot427 ///feature.428 void contract(Node a, Node b, bool r = true)429 {430 for(OutArcIt e(*this,b);e!=INVALID;) {431 OutArcIt f=e;432 ++f;433 if(r && target(e)==a) erase(e);434 else changeSource(e,a);435 e=f;436 }437 for(InArcIt e(*this,b);e!=INVALID;) {438 InArcIt f=e;439 ++f;440 if(r && source(e)==a) erase(e);441 else changeTarget(e,a);442 e=f;443 }444 erase(b);445 }446 447 ///Split a node.448 449 ///This function splits a node. First a new node is added to the digraph,450 ///then the source of each outgoing arc of \c n is moved to this new node.451 ///If \c connect is \c true (this is the default value), then a new arc452 ///from \c n to the newly created node is also added.453 ///\return The newly created node.454 ///455 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain456 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may457 ///be invalidated.458 ///459 ///\warning This functionality cannot be used together with the460 ///Snapshot feature.461 ///462 ///\todo It could be implemented in a bit faster way.463 Node split(Node n, bool connect = true) {464 Node b = addNode();465 for(OutArcIt e(*this,n);e!=INVALID;) {466 OutArcIt f=e;467 ++f;468 changeSource(e,b);469 e=f;470 }471 if (connect) addArc(n,b);472 return b;473 }474 475 ///Split an arc.476 477 ///This function splits an arc. First a new node \c b is added to478 ///the digraph, then the original arc is re-targeted to \c479 ///b. Finally an arc from \c b to the original target is added.480 ///481 ///\return The newly created node.482 ///483 ///\warning This functionality cannot be used together with the484 ///Snapshot feature.485 Node split(Arc e) {486 Node b = addNode();487 addArc(b,target(e));488 changeTarget(e,b);489 return b;490 }491 492 /// \brief Class to make a snapshot of the digraph and restore493 /// it later.494 ///495 /// Class to make a snapshot of the digraph and restore it later.496 ///497 /// The newly added nodes and arcs can be removed using the498 /// restore() function.499 ///500 /// \warning Arc and node deletions and other modifications (e.g.501 /// contracting, splitting, reversing arcs or nodes) cannot be502 /// restored. These events invalidate the snapshot.503 class Snapshot {504 protected:505 506 typedef Parent::NodeNotifier NodeNotifier;507 508 class NodeObserverProxy : public NodeNotifier::ObserverBase {509 public:510 511 NodeObserverProxy(Snapshot& _snapshot)512 : snapshot(_snapshot) {}513 514 using NodeNotifier::ObserverBase::attach;515 using NodeNotifier::ObserverBase::detach;516 using NodeNotifier::ObserverBase::attached;517 518 protected:519 520 virtual void add(const Node& node) {521 snapshot.addNode(node);522 }523 virtual void add(const std::vector<Node>& nodes) {524 for (int i = nodes.size() - 1; i >= 0; ++i) {525 snapshot.addNode(nodes[i]);526 }527 }528 virtual void erase(const Node& node) {529 snapshot.eraseNode(node);530 }531 virtual void erase(const std::vector<Node>& nodes) {532 for (int i = 0; i < int(nodes.size()); ++i) {533 snapshot.eraseNode(nodes[i]);534 }535 }536 virtual void build() {537 Node node;538 std::vector<Node> nodes;539 for (notifier()->first(node); node != INVALID;540 notifier()->next(node)) {541 nodes.push_back(node);542 }543 for (int i = nodes.size() - 1; i >= 0; --i) {544 snapshot.addNode(nodes[i]);545 }546 }547 virtual void clear() {548 Node node;549 for (notifier()->first(node); node != INVALID;550 notifier()->next(node)) {551 snapshot.eraseNode(node);552 }553 }554 555 Snapshot& snapshot;556 };557 558 class ArcObserverProxy : public ArcNotifier::ObserverBase {559 public:560 561 ArcObserverProxy(Snapshot& _snapshot)562 : snapshot(_snapshot) {}563 564 using ArcNotifier::ObserverBase::attach;565 using ArcNotifier::ObserverBase::detach;566 using ArcNotifier::ObserverBase::attached;567 568 protected:569 570 virtual void add(const Arc& arc) {571 snapshot.addArc(arc);572 }573 virtual void add(const std::vector<Arc>& arcs) {574 for (int i = arcs.size() - 1; i >= 0; ++i) {575 snapshot.addArc(arcs[i]);576 }577 }578 virtual void erase(const Arc& arc) {579 snapshot.eraseArc(arc);580 }581 virtual void erase(const std::vector<Arc>& arcs) {582 for (int i = 0; i < int(arcs.size()); ++i) {583 snapshot.eraseArc(arcs[i]);584 }585 }586 virtual void build() {587 Arc arc;588 std::vector<Arc> arcs;589 for (notifier()->first(arc); arc != INVALID;590 notifier()->next(arc)) {591 arcs.push_back(arc);592 }593 for (int i = arcs.size() - 1; i >= 0; --i) {594 snapshot.addArc(arcs[i]);595 }596 }597 virtual void clear() {598 Arc arc;599 for (notifier()->first(arc); arc != INVALID;600 notifier()->next(arc)) {601 snapshot.eraseArc(arc);602 }603 }604 605 Snapshot& snapshot;606 };607 608 ListDigraph *digraph;609 610 NodeObserverProxy node_observer_proxy;611 ArcObserverProxy arc_observer_proxy;612 613 std::list<Node> added_nodes;614 std::list<Arc> added_arcs;615 616 617 void addNode(const Node& node) {618 added_nodes.push_front(node);619 }620 void eraseNode(const Node& node) {621 std::list<Node>::iterator it =622 std::find(added_nodes.begin(), added_nodes.end(), node);623 if (it == added_nodes.end()) {624 clear();625 arc_observer_proxy.detach();626 throw NodeNotifier::ImmediateDetach();627 } else {628 added_nodes.erase(it);629 }630 }631 632 void addArc(const Arc& arc) {633 added_arcs.push_front(arc);634 }635 void eraseArc(const Arc& arc) {636 std::list<Arc>::iterator it =637 std::find(added_arcs.begin(), added_arcs.end(), arc);638 if (it == added_arcs.end()) {639 clear();640 node_observer_proxy.detach();641 throw ArcNotifier::ImmediateDetach();642 } else {643 added_arcs.erase(it);644 }645 }646 647 void attach(ListDigraph &_digraph) {648 digraph = &_digraph;649 node_observer_proxy.attach(digraph->notifier(Node()));650 arc_observer_proxy.attach(digraph->notifier(Arc()));651 }652 653 void detach() {654 node_observer_proxy.detach();655 arc_observer_proxy.detach();656 }657 658 bool attached() const {659 return node_observer_proxy.attached();660 }661 662 void clear() {663 added_nodes.clear();664 added_arcs.clear();665 }666 667 public:668 669 /// \brief Default constructor.670 ///671 /// Default constructor.672 /// To actually make a snapshot you must call save().673 Snapshot()674 : digraph(0), node_observer_proxy(*this),675 arc_observer_proxy(*this) {}676 677 /// \brief Constructor that immediately makes a snapshot.678 ///679 /// This constructor immediately makes a snapshot of the digraph.680 /// \param _digraph The digraph we make a snapshot of.681 Snapshot(ListDigraph &_digraph)682 : node_observer_proxy(*this),683 arc_observer_proxy(*this) {684 attach(_digraph);685 }686 687 /// \brief Make a snapshot.688 ///689 /// Make a snapshot of the digraph.690 ///691 /// This function can be called more than once. In case of a repeated692 /// call, the previous snapshot gets lost.693 /// \param _digraph The digraph we make the snapshot of.694 void save(ListDigraph &_digraph) {695 if (attached()) {696 detach();697 clear();698 }699 attach(_digraph);700 }701 702 /// \brief Undo the changes until the last snapshot.703 //704 /// Undo the changes until the last snapshot created by save().705 void restore() {706 detach();707 for(std::list<Arc>::iterator it = added_arcs.begin();708 it != added_arcs.end(); ++it) {709 digraph->erase(*it);710 }711 for(std::list<Node>::iterator it = added_nodes.begin();712 it != added_nodes.end(); ++it) {713 digraph->erase(*it);714 }715 clear();716 }717 718 /// \brief Gives back true when the snapshot is valid.719 ///720 /// Gives back true when the snapshot is valid.721 bool valid() const {722 return attached();723 }724 };725 726 };727 728 ///@}729 730 class ListGraphBase {731 732 protected:733 734 struct NodeT {735 int first_out;736 int prev, next;737 };738 739 struct ArcT {740 int target;741 int prev_out, next_out;742 };743 744 std::vector<NodeT> nodes;745 746 int first_node;747 748 int first_free_node;749 750 std::vector<ArcT> arcs;751 752 int first_free_arc;753 754 public:755 756 typedef ListGraphBase Digraph;757 758 class Node;759 class Arc;760 class Edge;761 762 class Node {763 friend class ListGraphBase;764 protected:765 766 int id;767 explicit Node(int pid) { id = pid;}768 769 public:770 Node() {}771 Node (Invalid) { id = -1; }772 bool operator==(const Node& node) const {return id == node.id;}773 bool operator!=(const Node& node) const {return id != node.id;}774 bool operator<(const Node& node) const {return id < node.id;}775 };776 777 class Edge {778 friend class ListGraphBase;779 protected:780 781 int id;782 explicit Edge(int pid) { id = pid;}783 784 public:785 Edge() {}786 Edge (Invalid) { id = -1; }787 bool operator==(const Edge& edge) const {return id == edge.id;}788 bool operator!=(const Edge& edge) const {return id != edge.id;}789 bool operator<(const Edge& edge) const {return id < edge.id;}790 };791 792 class Arc {793 friend class ListGraphBase;794 protected:795 796 int id;797 explicit Arc(int pid) { id = pid;}798 799 public:800 operator Edge() const { return edgeFromId(id / 2); }801 802 Arc() {}803 Arc (Invalid) { id = -1; }804 bool operator==(const Arc& arc) const {return id == arc.id;}805 bool operator!=(const Arc& arc) const {return id != arc.id;}806 bool operator<(const Arc& arc) const {return id < arc.id;}807 };808 809 810 811 ListGraphBase()812 : nodes(), first_node(-1),813 first_free_node(-1), arcs(), first_free_arc(-1) {}814 815 816 int maxNodeId() const { return nodes.size()-1; }817 int maxEdgeId() const { return arcs.size() / 2 - 1; }818 int maxArcId() const { return arcs.size()-1; }819 820 Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }821 Node target(Arc e) const { return Node(arcs[e.id].target); }822 823 Node u(Edge e) const { return Node(arcs[2 * e.id].target); }824 Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }825 826 static bool direction(Arc e) {827 return (e.id & 1) == 1;828 }829 830 static Arc direct(Edge e, bool d) {831 return Arc(e.id * 2 + (d ? 1 : 0));832 }833 834 void first(Node& node) const {835 node.id = first_node;836 }837 838 void next(Node& node) const {839 node.id = nodes[node.id].next;840 }841 842 void first(Arc& e) const {843 int n = first_node;844 while (n != -1 && nodes[n].first_out == -1) {845 n = nodes[n].next;846 }847 e.id = (n == -1) ? -1 : nodes[n].first_out;848 }849 850 void next(Arc& e) const {851 if (arcs[e.id].next_out != -1) {852 e.id = arcs[e.id].next_out;853 } else {854 int n = nodes[arcs[e.id ^ 1].target].next;855 while(n != -1 && nodes[n].first_out == -1) {856 n = nodes[n].next;857 }858 e.id = (n == -1) ? -1 : nodes[n].first_out;859 }860 }861 862 void first(Edge& e) const {863 int n = first_node;864 while (n != -1) {865 e.id = nodes[n].first_out;866 while ((e.id & 1) != 1) {867 e.id = arcs[e.id].next_out;868 }869 if (e.id != -1) {870 e.id /= 2;871 return;872 }873 n = nodes[n].next;874 }875 e.id = -1;876 }877 878 void next(Edge& e) const {879 int n = arcs[e.id * 2].target;880 e.id = arcs[(e.id * 2) | 1].next_out;881 while ((e.id & 1) != 1) {882 e.id = arcs[e.id].next_out;883 }884 if (e.id != -1) {885 e.id /= 2;886 return;887 }888 n = nodes[n].next;889 while (n != -1) {890 e.id = nodes[n].first_out;891 while ((e.id & 1) != 1) {892 e.id = arcs[e.id].next_out;893 }894 if (e.id != -1) {895 e.id /= 2;896 return;897 }898 n = nodes[n].next;899 }900 e.id = -1;901 }902 903 void firstOut(Arc &e, const Node& v) const {904 e.id = nodes[v.id].first_out;905 }906 void nextOut(Arc &e) const {907 e.id = arcs[e.id].next_out;908 }909 910 void firstIn(Arc &e, const Node& v) const {911 e.id = ((nodes[v.id].first_out) ^ 1);912 if (e.id == -2) e.id = -1;913 }914 void nextIn(Arc &e) const {915 e.id = ((arcs[e.id ^ 1].next_out) ^ 1);916 if (e.id == -2) e.id = -1;917 }918 919 void firstInc(Edge &e, bool& d, const Node& v) const {920 int a = nodes[v.id].first_out;921 if (a != -1 ) {922 e.id = a / 2;923 d = ((a & 1) == 1);924 } else {925 e.id = -1;926 d = true;927 }928 }929 void nextInc(Edge &e, bool& d) const {930 int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);931 if (a != -1 ) {932 e.id = a / 2;933 d = ((a & 1) == 1);934 } else {935 e.id = -1;936 d = true;937 }938 }939 940 static int id(Node v) { return v.id; }941 static int id(Arc e) { return e.id; }942 static int id(Edge e) { return e.id; }943 944 static Node nodeFromId(int id) { return Node(id);}945 static Arc arcFromId(int id) { return Arc(id);}946 static Edge edgeFromId(int id) { return Edge(id);}947 948 Node addNode() {949 int n;950 951 if(first_free_node==-1) {952 n = nodes.size();953 nodes.push_back(NodeT());954 } else {955 n = first_free_node;956 first_free_node = nodes[n].next;957 }958 959 nodes[n].next = first_node;960 if (first_node != -1) nodes[first_node].prev = n;961 first_node = n;962 nodes[n].prev = -1;963 964 nodes[n].first_out = -1;965 966 return Node(n);967 }968 969 Edge addEdge(Node u, Node v) {970 int n;971 972 if (first_free_arc == -1) {973 n = arcs.size();974 arcs.push_back(ArcT());975 arcs.push_back(ArcT());976 } else {977 n = first_free_arc;978 first_free_arc = arcs[n].next_out;979 }980 981 arcs[n].target = u.id;982 arcs[n | 1].target = v.id;983 984 arcs[n].next_out = nodes[v.id].first_out;985 if (nodes[v.id].first_out != -1) {986 arcs[nodes[v.id].first_out].prev_out = n;987 }988 arcs[n].prev_out = -1;989 nodes[v.id].first_out = n;990 991 arcs[n | 1].next_out = nodes[u.id].first_out;992 if (nodes[u.id].first_out != -1) {993 arcs[nodes[u.id].first_out].prev_out = (n | 1);994 }995 arcs[n | 1].prev_out = -1;996 nodes[u.id].first_out = (n | 1);997 998 return Edge(n / 2);999 }1000 1001 void erase(const Node& node) {1002 int n = node.id;1003 1004 if(nodes[n].next != -1) {1005 nodes[nodes[n].next].prev = nodes[n].prev;1006 }1007 1008 if(nodes[n].prev != -1) {1009 nodes[nodes[n].prev].next = nodes[n].next;1010 } else {1011 first_node = nodes[n].next;1012 }1013 1014 nodes[n].next = first_free_node;1015 first_free_node = n;1016 1017 }1018 1019 void erase(const Edge& edge) {1020 int n = edge.id * 2;1021 1022 if (arcs[n].next_out != -1) {1023 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;1024 }1025 1026 if (arcs[n].prev_out != -1) {1027 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;1028 } else {1029 nodes[arcs[n | 1].target].first_out = arcs[n].next_out;1030 }1031 1032 if (arcs[n | 1].next_out != -1) {1033 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;1034 }1035 1036 if (arcs[n | 1].prev_out != -1) {1037 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;1038 } else {1039 nodes[arcs[n].target].first_out = arcs[n | 1].next_out;1040 }1041 1042 arcs[n].next_out = first_free_arc;1043 first_free_arc = n;1044 1045 }1046 1047 void clear() {1048 arcs.clear();1049 nodes.clear();1050 first_node = first_free_node = first_free_arc = -1;1051 }1052 1053 protected:1054 1055 void changeTarget(Edge e, Node n) {1056 if(arcs[2 * e.id].next_out != -1) {1057 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;1058 }1059 if(arcs[2 * e.id].prev_out != -1) {1060 arcs[arcs[2 * e.id].prev_out].next_out =1061 arcs[2 * e.id].next_out;1062 } else {1063 nodes[arcs[(2 * e.id) | 1].target].first_out =1064 arcs[2 * e.id].next_out;1065 }1066 1067 if (nodes[n.id].first_out != -1) {1068 arcs[nodes[n.id].first_out].prev_out = 2 * e.id;1069 }1070 arcs[(2 * e.id) | 1].target = n.id;1071 arcs[2 * e.id].prev_out = -1;1072 arcs[2 * e.id].next_out = nodes[n.id].first_out;1073 nodes[n.id].first_out = 2 * e.id;1074 }1075 1076 void changeSource(Edge e, Node n) {1077 if(arcs[(2 * e.id) | 1].next_out != -1) {1078 arcs[arcs[(2 * e.id) | 1].next_out].prev_out =1079 arcs[(2 * e.id) | 1].prev_out;1080 }1081 if(arcs[(2 * e.id) | 1].prev_out != -1) {1082 arcs[arcs[(2 * e.id) | 1].prev_out].next_out =1083 arcs[(2 * e.id) | 1].next_out;1084 } else {1085 nodes[arcs[2 * e.id].target].first_out =1086 arcs[(2 * e.id) | 1].next_out;1087 }1088 1089 if (nodes[n.id].first_out != -1) {1090 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);1091 }1092 arcs[2 * e.id].target = n.id;1093 arcs[(2 * e.id) | 1].prev_out = -1;1094 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;1095 nodes[n.id].first_out = ((2 * e.id) | 1);1096 }1097 1098 };1099 1100 typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;1101 1102 1103 /// \addtogroup graphs1104 /// @{1105 1106 ///A general undirected graph structure.1107 1108 ///\ref ListGraph is a simple and fast <em>undirected graph</em>1109 ///implementation based on static linked lists that are stored in1110 ///\c std::vector structures.1111 ///1112 ///It conforms to the \ref concepts::Graph "Graph concept" and it1113 ///also provides several useful additional functionalities.1114 ///Most of the member functions and nested classes are documented1115 ///only in the concept class.1116 ///1117 ///An important extra feature of this graph implementation is that1118 ///its maps are real \ref concepts::ReferenceMap "reference map"s.1119 ///1120 ///\sa concepts::Graph1121 1122 class ListGraph : public ExtendedListGraphBase {1123 private:1124 ///ListGraph is \e not copy constructible. Use copyGraph() instead.1125 1126 ///ListGraph is \e not copy constructible. Use copyGraph() instead.1127 ///1128 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};1129 ///\brief Assignment of ListGraph to another one is \e not allowed.1130 ///Use copyGraph() instead.1131 1132 ///Assignment of ListGraph to another one is \e not allowed.1133 ///Use copyGraph() instead.1134 void operator=(const ListGraph &) {}1135 public:1136 /// Constructor1137 1138 /// Constructor.1139 ///1140 ListGraph() {}1141 1142 typedef ExtendedListGraphBase Parent;1143 1144 typedef Parent::OutArcIt IncEdgeIt;1145 1146 /// \brief Add a new node to the graph.1147 ///1148 /// Add a new node to the graph.1149 /// \return the new node.1150 Node addNode() { return Parent::addNode(); }1151 1152 /// \brief Add a new edge to the graph.1153 ///1154 /// Add a new edge to the graph with source node \c s1155 /// and target node \c t.1156 /// \return the new edge.1157 Edge addEdge(const Node& s, const Node& t) {1158 return Parent::addEdge(s, t);1159 }1160 /// \brief Change the source of \c e to \c n1161 ///1162 /// This function changes the source of \c e to \c n.1163 ///1164 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s1165 ///referencing the changed arc remain1166 ///valid. However <tt>OutArcIt</tt>s are invalidated.1167 ///1168 ///\warning This functionality cannot be used together with the1169 ///Snapshot feature.1170 void changeSource(Edge e, Node n) {1171 Parent::changeSource(e,n);1172 }1173 /// \brief Change the target of \c e to \c n1174 ///1175 /// This function changes the target of \c e to \c n.1176 ///1177 /// \note The <tt>ArcIt</tt>s referencing the changed arc remain1178 /// valid. However the other iterators may be invalidated.1179 ///1180 ///\warning This functionality cannot be used together with the1181 ///Snapshot feature.1182 void changeTarget(Edge e, Node n) {1183 Parent::changeTarget(e,n);1184 }1185 /// \brief Change the source of \c e to \c n1186 ///1187 /// This function changes the source of \c e to \c n.1188 /// It also changes the proper node of the represented edge.1189 ///1190 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s1191 ///referencing the changed arc remain1192 ///valid. However <tt>OutArcIt</tt>s are invalidated.1193 ///1194 ///\warning This functionality cannot be used together with the1195 ///Snapshot feature.1196 void changeSource(Arc e, Node n) {1197 if (Parent::direction(e)) {1198 Parent::changeSource(e,n);1199 } else {1200 Parent::changeTarget(e,n);1201 }1202 }1203 /// \brief Change the target of \c e to \c n1204 ///1205 /// This function changes the target of \c e to \c n.1206 /// It also changes the proper node of the represented edge.1207 ///1208 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s1209 ///referencing the changed arc remain1210 ///valid. However <tt>InArcIt</tt>s are invalidated.1211 ///1212 ///\warning This functionality cannot be used together with the1213 ///Snapshot feature.1214 void changeTarget(Arc e, Node n) {1215 if (Parent::direction(e)) {1216 Parent::changeTarget(e,n);1217 } else {1218 Parent::changeSource(e,n);1219 }1220 }1221 /// \brief Contract two nodes.1222 ///1223 /// This function contracts two nodes.1224 /// Node \p b will be removed but instead of deleting1225 /// its neighboring arcs, they will be joined to \p a.1226 /// The last parameter \p r controls whether to remove loops. \c true1227 /// means that loops will be removed.1228 ///1229 /// \note The <tt>ArcIt</tt>s referencing a moved arc remain1230 /// valid.1231 ///1232 ///\warning This functionality cannot be used together with the1233 ///Snapshot feature.1234 void contract(Node a, Node b, bool r = true) {1235 for(IncEdgeIt e(*this, b); e!=INVALID;) {1236 IncEdgeIt f = e; ++f;1237 if (r && runningNode(e) == a) {1238 erase(e);1239 } else if (source(e) == b) {1240 changeSource(e, a);1241 } else {1242 changeTarget(e, a);1243 }1244 e = f;1245 }1246 erase(b);1247 }1248 1249 1250 /// \brief Class to make a snapshot of the graph and restore1251 /// it later.1252 ///1253 /// Class to make a snapshot of the graph and restore it later.1254 ///1255 /// The newly added nodes and edges can be removed1256 /// using the restore() function.1257 ///1258 /// \warning Edge and node deletions and other modifications1259 /// (e.g. changing nodes of edges, contracting nodes) cannot be1260 /// restored. These events invalidate the snapshot.1261 class Snapshot {1262 protected:1263 1264 typedef Parent::NodeNotifier NodeNotifier;1265 1266 class NodeObserverProxy : public NodeNotifier::ObserverBase {1267 public:1268 1269 NodeObserverProxy(Snapshot& _snapshot)1270 : snapshot(_snapshot) {}1271 1272 using NodeNotifier::ObserverBase::attach;1273 using NodeNotifier::ObserverBase::detach;1274 using NodeNotifier::ObserverBase::attached;1275 1276 protected:1277 1278 virtual void add(const Node& node) {1279 snapshot.addNode(node);1280 }1281 virtual void add(const std::vector<Node>& nodes) {1282 for (int i = nodes.size() - 1; i >= 0; ++i) {1283 snapshot.addNode(nodes[i]);1284 }1285 }1286 virtual void erase(const Node& node) {1287 snapshot.eraseNode(node);1288 }1289 virtual void erase(const std::vector<Node>& nodes) {1290 for (int i = 0; i < int(nodes.size()); ++i) {1291 snapshot.eraseNode(nodes[i]);1292 }1293 }1294 virtual void build() {1295 Node node;1296 std::vector<Node> nodes;1297 for (notifier()->first(node); node != INVALID;1298 notifier()->next(node)) {1299 nodes.push_back(node);1300 }1301 for (int i = nodes.size() - 1; i >= 0; --i) {1302 snapshot.addNode(nodes[i]);1303 }1304 }1305 virtual void clear() {1306 Node node;1307 for (notifier()->first(node); node != INVALID;1308 notifier()->next(node)) {1309 snapshot.eraseNode(node);1310 }1311 }1312 1313 Snapshot& snapshot;1314 };1315 1316 class EdgeObserverProxy : public EdgeNotifier::ObserverBase {1317 public:1318 1319 EdgeObserverProxy(Snapshot& _snapshot)1320 : snapshot(_snapshot) {}1321 1322 using EdgeNotifier::ObserverBase::attach;1323 using EdgeNotifier::ObserverBase::detach;1324 using EdgeNotifier::ObserverBase::attached;1325 1326 protected:1327 1328 virtual void add(const Edge& edge) {1329 snapshot.addEdge(edge);1330 }1331 virtual void add(const std::vector<Edge>& edges) {1332 for (int i = edges.size() - 1; i >= 0; ++i) {1333 snapshot.addEdge(edges[i]);1334 }1335 }1336 virtual void erase(const Edge& edge) {1337 snapshot.eraseEdge(edge);1338 }1339 virtual void erase(const std::vector<Edge>& edges) {1340 for (int i = 0; i < int(edges.size()); ++i) {1341 snapshot.eraseEdge(edges[i]);1342 }1343 }1344 virtual void build() {1345 Edge edge;1346 std::vector<Edge> edges;1347 for (notifier()->first(edge); edge != INVALID;1348 notifier()->next(edge)) {1349 edges.push_back(edge);1350 }1351 for (int i = edges.size() - 1; i >= 0; --i) {1352 snapshot.addEdge(edges[i]);1353 }1354 }1355 virtual void clear() {1356 Edge edge;1357 for (notifier()->first(edge); edge != INVALID;1358 notifier()->next(edge)) {1359 snapshot.eraseEdge(edge);1360 }1361 }1362 1363 Snapshot& snapshot;1364 };1365 1366 ListGraph *graph;1367 1368 NodeObserverProxy node_observer_proxy;1369 EdgeObserverProxy edge_observer_proxy;1370 1371 std::list<Node> added_nodes;1372 std::list<Edge> added_edges;1373 1374 1375 void addNode(const Node& node) {1376 added_nodes.push_front(node);1377 }1378 void eraseNode(const Node& node) {1379 std::list<Node>::iterator it =1380 std::find(added_nodes.begin(), added_nodes.end(), node);1381 if (it == added_nodes.end()) {1382 clear();1383 edge_observer_proxy.detach();1384 throw NodeNotifier::ImmediateDetach();1385 } else {1386 added_nodes.erase(it);1387 }1388 }1389 1390 void addEdge(const Edge& edge) {1391 added_edges.push_front(edge);1392 }1393 void eraseEdge(const Edge& edge) {1394 std::list<Edge>::iterator it =1395 std::find(added_edges.begin(), added_edges.end(), edge);1396 if (it == added_edges.end()) {1397 clear();1398 node_observer_proxy.detach();1399 throw EdgeNotifier::ImmediateDetach();1400 } else {1401 added_edges.erase(it);1402 }1403 }1404 1405 void attach(ListGraph &_graph) {1406 graph = &_graph;1407 node_observer_proxy.attach(graph->notifier(Node()));1408 edge_observer_proxy.attach(graph->notifier(Edge()));1409 }1410 1411 void detach() {1412 node_observer_proxy.detach();1413 edge_observer_proxy.detach();1414 }1415 1416 bool attached() const {1417 return node_observer_proxy.attached();1418 }1419 1420 void clear() {1421 added_nodes.clear();1422 added_edges.clear();1423 }1424 1425 public:1426 1427 /// \brief Default constructor.1428 ///1429 /// Default constructor.1430 /// To actually make a snapshot you must call save().1431 Snapshot()1432 : graph(0), node_observer_proxy(*this),1433 edge_observer_proxy(*this) {}1434 1435 /// \brief Constructor that immediately makes a snapshot.1436 ///1437 /// This constructor immediately makes a snapshot of the graph.1438 /// \param _graph The graph we make a snapshot of.1439 Snapshot(ListGraph &_graph)1440 : node_observer_proxy(*this),1441 edge_observer_proxy(*this) {1442 attach(_graph);1443 }1444 1445 /// \brief Make a snapshot.1446 ///1447 /// Make a snapshot of the graph.1448 ///1449 /// This function can be called more than once. In case of a repeated1450 /// call, the previous snapshot gets lost.1451 /// \param _graph The graph we make the snapshot of.1452 void save(ListGraph &_graph) {1453 if (attached()) {1454 detach();1455 clear();1456 }1457 attach(_graph);1458 }1459 1460 /// \brief Undo the changes until the last snapshot.1461 //1462 /// Undo the changes until the last snapshot created by save().1463 void restore() {1464 detach();1465 for(std::list<Edge>::iterator it = added_edges.begin();1466 it != added_edges.end(); ++it) {1467 graph->erase(*it);1468 }1469 for(std::list<Node>::iterator it = added_nodes.begin();1470 it != added_nodes.end(); ++it) {1471 graph->erase(*it);1472 }1473 clear();1474 }1475 1476 /// \brief Gives back true when the snapshot is valid.1477 ///1478 /// Gives back true when the snapshot is valid.1479 bool valid() const {1480 return attached();1481 }1482 };1483 };1484 1485 /// @}1486 } //namespace lemon1487 1488 1489 #endif
Note: See TracChangeset
for help on using the changeset viewer.