Branch data Line data Source code
1 : : /* -*- mode: C++; indent-tabs-mode: nil; -*-
2 : : *
3 : : * This file is a part of LEMON, a generic C++ optimization library.
4 : : *
5 : : * Copyright (C) 2003-2010
6 : : * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 : : * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 : : *
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.
12 : : *
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
15 : : * purpose.
16 : : *
17 : : */
18 : :
19 : : #ifndef LEMON_LIST_GRAPH_H
20 : : #define LEMON_LIST_GRAPH_H
21 : :
22 : : ///\ingroup graphs
23 : : ///\file
24 : : ///\brief ListDigraph and ListGraph classes.
25 : :
26 : : #include <lemon/core.h>
27 : : #include <lemon/error.h>
28 : : #include <lemon/bits/graph_extender.h>
29 : :
30 : : #include <vector>
31 : : #include <list>
32 : :
33 : : namespace lemon {
34 : :
35 : : class ListDigraph;
36 : :
37 : 42 : class ListDigraphBase {
38 : :
39 : : protected:
40 : : struct NodeT {
41 : : int first_in, first_out;
42 : : int prev, next;
43 : : };
44 : :
45 : : struct ArcT {
46 : : int target, source;
47 : : int prev_in, prev_out;
48 : : int next_in, next_out;
49 : : };
50 : :
51 : : std::vector<NodeT> nodes;
52 : :
53 : : int first_node;
54 : :
55 : : int first_free_node;
56 : :
57 : : std::vector<ArcT> arcs;
58 : :
59 : : int first_free_arc;
60 : :
61 : : public:
62 : :
63 : : typedef ListDigraphBase Digraph;
64 : :
65 : : class Node {
66 : : friend class ListDigraphBase;
67 : : friend class ListDigraph;
68 : : protected:
69 : :
70 : : int id;
71 : 6157 : explicit Node(int pid) { id = pid;}
72 : :
73 : : public:
74 : 8123 : Node() {}
75 : 14526 : Node (Invalid) { id = -1; }
76 : 3124 : bool operator==(const Node& node) const {return id == node.id;}
77 : 29962 : bool operator!=(const Node& node) const {return id != node.id;}
78 : 0 : bool operator<(const Node& node) const {return id < node.id;}
79 : : };
80 : :
81 : : class Arc {
82 : : friend class ListDigraphBase;
83 : : friend class ListDigraph;
84 : : protected:
85 : :
86 : : int id;
87 : 649 : explicit Arc(int pid) { id = pid;}
88 : :
89 : : public:
90 : 6058 : Arc() {}
91 : 6722 : Arc (Invalid) { id = -1; }
92 : 874 : bool operator==(const Arc& arc) const {return id == arc.id;}
93 : 9030 : bool operator!=(const Arc& arc) const {return id != arc.id;}
94 : : bool operator<(const Arc& arc) const {return id < arc.id;}
95 : : };
96 : :
97 : :
98 : :
99 : 38 : ListDigraphBase()
100 : : : nodes(), first_node(-1),
101 [ + - ]: 38 : first_free_node(-1), arcs(), first_free_arc(-1) {}
102 : :
103 : :
104 : 1966 : int maxNodeId() const { return nodes.size()-1; }
105 : 0 : int maxArcId() const { return arcs.size()-1; }
106 : :
107 : 6990 : Node source(Arc e) const { return Node(arcs[e.id].source); }
108 : 4834 : Node target(Arc e) const { return Node(arcs[e.id].target); }
109 : :
110 : :
111 : 1617 : void first(Node& node) const {
112 : 1617 : node.id = first_node;
113 : 1617 : }
114 : :
115 : 10258 : void next(Node& node) const {
116 : 10258 : node.id = nodes[node.id].next;
117 : 10258 : }
118 : :
119 : :
120 : 36 : void first(Arc& arc) const {
121 : : int n;
122 [ - + ]: 72 : for(n = first_node;
123 [ + - ][ - + ]: 36 : n != -1 && nodes[n].first_out == -1;
124 : 0 : n = nodes[n].next) {}
125 [ + - ]: 36 : arc.id = (n == -1) ? -1 : nodes[n].first_out;
126 : 36 : }
127 : :
128 : 660 : void next(Arc& arc) const {
129 [ + + ]: 660 : if (arcs[arc.id].next_out != -1) {
130 : 222 : arc.id = arcs[arc.id].next_out;
131 : : } else {
132 : : int n;
133 [ + + ]: 948 : for(n = nodes[arcs[arc.id].source].next;
134 [ + + ][ + + ]: 474 : n != -1 && nodes[n].first_out == -1;
135 : 36 : n = nodes[n].next) {}
136 [ + + ]: 438 : arc.id = (n == -1) ? -1 : nodes[n].first_out;
137 : : }
138 : 660 : }
139 : :
140 : 1132 : void firstOut(Arc &e, const Node& v) const {
141 : 1132 : e.id = nodes[v.id].first_out;
142 : 1132 : }
143 : 611 : void nextOut(Arc &e) const {
144 : 611 : e.id=arcs[e.id].next_out;
145 : 611 : }
146 : :
147 : 2028 : void firstIn(Arc &e, const Node& v) const {
148 : 2028 : e.id = nodes[v.id].first_in;
149 : 2028 : }
150 : 1194 : void nextIn(Arc &e) const {
151 : 1194 : e.id=arcs[e.id].next_in;
152 : 1194 : }
153 : :
154 : :
155 : 61978 : static int id(Node v) { return v.id; }
156 : 660 : static int id(Arc e) { return e.id; }
157 : :
158 : 0 : static Node nodeFromId(int id) { return Node(id);}
159 : 0 : static Arc arcFromId(int id) { return Arc(id);}
160 : :
161 : : bool valid(Node n) const {
162 : : return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
163 : : nodes[n.id].prev != -2;
164 : : }
165 : :
166 : : bool valid(Arc a) const {
167 : : return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
168 : : arcs[a.id].prev_in != -2;
169 : : }
170 : :
171 : 245 : Node addNode() {
172 : : int n;
173 : :
174 [ + + ]: 245 : if(first_free_node==-1) {
175 : 184 : n = nodes.size();
176 [ + - ]: 184 : nodes.push_back(NodeT());
177 : : } else {
178 : 61 : n = first_free_node;
179 : 61 : first_free_node = nodes[n].next;
180 : : }
181 : :
182 : 245 : nodes[n].next = first_node;
183 [ + + ]: 245 : if(first_node != -1) nodes[first_node].prev = n;
184 : 245 : first_node = n;
185 : 245 : nodes[n].prev = -1;
186 : :
187 : 245 : nodes[n].first_in = nodes[n].first_out = -1;
188 : :
189 : 245 : return Node(n);
190 : : }
191 : :
192 : 649 : Arc addArc(Node u, Node v) {
193 : : int n;
194 : :
195 [ + + ]: 649 : if (first_free_arc == -1) {
196 : 207 : n = arcs.size();
197 [ + - ]: 207 : arcs.push_back(ArcT());
198 : : } else {
199 : 442 : n = first_free_arc;
200 : 442 : first_free_arc = arcs[n].next_in;
201 : : }
202 : :
203 : 649 : arcs[n].source = u.id;
204 : 649 : arcs[n].target = v.id;
205 : :
206 : 649 : arcs[n].next_out = nodes[u.id].first_out;
207 [ + + ]: 649 : if(nodes[u.id].first_out != -1) {
208 : 316 : arcs[nodes[u.id].first_out].prev_out = n;
209 : : }
210 : :
211 : 649 : arcs[n].next_in = nodes[v.id].first_in;
212 [ + + ]: 649 : if(nodes[v.id].first_in != -1) {
213 : 175 : arcs[nodes[v.id].first_in].prev_in = n;
214 : : }
215 : :
216 : 649 : arcs[n].prev_in = arcs[n].prev_out = -1;
217 : :
218 : 649 : nodes[u.id].first_out = nodes[v.id].first_in = n;
219 : :
220 : 649 : return Arc(n);
221 : : }
222 : :
223 : 159 : void erase(const Node& node) {
224 : 159 : int n = node.id;
225 : :
226 [ + - ]: 159 : if(nodes[n].next != -1) {
227 : 159 : nodes[nodes[n].next].prev = nodes[n].prev;
228 : : }
229 : :
230 [ + + ]: 159 : if(nodes[n].prev != -1) {
231 : 5 : nodes[nodes[n].prev].next = nodes[n].next;
232 : : } else {
233 : 154 : first_node = nodes[n].next;
234 : : }
235 : :
236 : 159 : nodes[n].next = first_free_node;
237 : 159 : first_free_node = n;
238 : 159 : nodes[n].prev = -2;
239 : :
240 : 159 : }
241 : :
242 : 633 : void erase(const Arc& arc) {
243 : 633 : int n = arc.id;
244 : :
245 [ + + ]: 633 : if(arcs[n].next_in!=-1) {
246 : 170 : arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
247 : : }
248 : :
249 [ + + ]: 633 : if(arcs[n].prev_in!=-1) {
250 : 19 : arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
251 : : } else {
252 : 614 : nodes[arcs[n].target].first_in = arcs[n].next_in;
253 : : }
254 : :
255 : :
256 [ + + ]: 633 : if(arcs[n].next_out!=-1) {
257 : 230 : arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
258 : : }
259 : :
260 [ + + ]: 633 : if(arcs[n].prev_out!=-1) {
261 : 118 : arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
262 : : } else {
263 : 515 : nodes[arcs[n].source].first_out = arcs[n].next_out;
264 : : }
265 : :
266 : 633 : arcs[n].next_in = first_free_arc;
267 : 633 : first_free_arc = n;
268 : 633 : arcs[n].prev_in = -2;
269 : 633 : }
270 : :
271 : : void clear() {
272 : : arcs.clear();
273 : : nodes.clear();
274 : : first_node = first_free_node = first_free_arc = -1;
275 : : }
276 : :
277 : : protected:
278 : : void changeTarget(Arc e, Node n)
279 : : {
280 : : if(arcs[e.id].next_in != -1)
281 : : arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
282 : : if(arcs[e.id].prev_in != -1)
283 : : arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
284 : : else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
285 : : if (nodes[n.id].first_in != -1) {
286 : : arcs[nodes[n.id].first_in].prev_in = e.id;
287 : : }
288 : : arcs[e.id].target = n.id;
289 : : arcs[e.id].prev_in = -1;
290 : : arcs[e.id].next_in = nodes[n.id].first_in;
291 : : nodes[n.id].first_in = e.id;
292 : : }
293 : : void changeSource(Arc e, Node n)
294 : : {
295 : : if(arcs[e.id].next_out != -1)
296 : : arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
297 : : if(arcs[e.id].prev_out != -1)
298 : : arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
299 : : else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
300 : : if (nodes[n.id].first_out != -1) {
301 : : arcs[nodes[n.id].first_out].prev_out = e.id;
302 : : }
303 : : arcs[e.id].source = n.id;
304 : : arcs[e.id].prev_out = -1;
305 : : arcs[e.id].next_out = nodes[n.id].first_out;
306 : : nodes[n.id].first_out = e.id;
307 : : }
308 : :
309 : : };
310 : :
311 : : typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
312 : :
313 : : /// \addtogroup graphs
314 : : /// @{
315 : :
316 : : ///A general directed graph structure.
317 : :
318 : : ///\ref ListDigraph is a versatile and fast directed graph
319 : : ///implementation based on linked lists that are stored in
320 : : ///\c std::vector structures.
321 : : ///
322 : : ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
323 : : ///and it also provides several useful additional functionalities.
324 : : ///Most of its member functions and nested classes are documented
325 : : ///only in the concept class.
326 : : ///
327 : : ///This class provides only linear time counting for nodes and arcs.
328 : : ///
329 : : ///\sa concepts::Digraph
330 : : ///\sa ListGraph
331 : 42 : class ListDigraph : public ExtendedListDigraphBase {
332 : : typedef ExtendedListDigraphBase Parent;
333 : :
334 : : private:
335 : : /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
336 : : ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
337 : : /// \brief Assignment of a digraph to another one is \e not allowed.
338 : : /// Use DigraphCopy instead.
339 : : void operator=(const ListDigraph &) {}
340 : : public:
341 : :
342 : : /// Constructor
343 : :
344 : : /// Constructor.
345 : : ///
346 : 76 : ListDigraph() {}
347 : :
348 : : ///Add a new node to the digraph.
349 : :
350 : : ///This function adds a new node to the digraph.
351 : : ///\return The new node.
352 : 490 : Node addNode() { return Parent::addNode(); }
353 : :
354 : : ///Add a new arc to the digraph.
355 : :
356 : : ///This function adds a new arc to the digraph with source node \c s
357 : : ///and target node \c t.
358 : : ///\return The new arc.
359 : 649 : Arc addArc(Node s, Node t) {
360 : 649 : return Parent::addArc(s, t);
361 : : }
362 : :
363 : : ///\brief Erase a node from the digraph.
364 : : ///
365 : : ///This function erases the given node along with its outgoing and
366 : : ///incoming arcs from the digraph.
367 : : ///
368 : : ///\note All iterators referencing the removed node or the connected
369 : : ///arcs are invalidated, of course.
370 : 318 : void erase(Node n) { Parent::erase(n); }
371 : :
372 : : ///\brief Erase an arc from the digraph.
373 : : ///
374 : : ///This function erases the given arc from the digraph.
375 : : ///
376 : : ///\note All iterators referencing the removed arc are invalidated,
377 : : ///of course.
378 : 728 : void erase(Arc a) { Parent::erase(a); }
379 : :
380 : : /// Node validity check
381 : :
382 : : /// This function gives back \c true if the given node is valid,
383 : : /// i.e. it is a real node of the digraph.
384 : : ///
385 : : /// \warning A removed node could become valid again if new nodes are
386 : : /// added to the digraph.
387 : : bool valid(Node n) const { return Parent::valid(n); }
388 : :
389 : : /// Arc validity check
390 : :
391 : : /// This function gives back \c true if the given arc is valid,
392 : : /// i.e. it is a real arc of the digraph.
393 : : ///
394 : : /// \warning A removed arc could become valid again if new arcs are
395 : : /// added to the digraph.
396 : : bool valid(Arc a) const { return Parent::valid(a); }
397 : :
398 : : /// Change the target node of an arc
399 : :
400 : : /// This function changes the target node of the given arc \c a to \c n.
401 : : ///
402 : : ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
403 : : ///arc remain valid, but \c InArcIt iterators are invalidated.
404 : : ///
405 : : ///\warning This functionality cannot be used together with the Snapshot
406 : : ///feature.
407 : : void changeTarget(Arc a, Node n) {
408 : : Parent::changeTarget(a,n);
409 : : }
410 : : /// Change the source node of an arc
411 : :
412 : : /// This function changes the source node of the given arc \c a to \c n.
413 : : ///
414 : : ///\note \c InArcIt iterators referencing the changed arc remain
415 : : ///valid, but \c ArcIt and \c OutArcIt iterators are invalidated.
416 : : ///
417 : : ///\warning This functionality cannot be used together with the Snapshot
418 : : ///feature.
419 : : void changeSource(Arc a, Node n) {
420 : : Parent::changeSource(a,n);
421 : : }
422 : :
423 : : /// Reverse the direction of an arc.
424 : :
425 : : /// This function reverses the direction of the given arc.
426 : : ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
427 : : ///the changed arc are invalidated.
428 : : ///
429 : : ///\warning This functionality cannot be used together with the Snapshot
430 : : ///feature.
431 : : void reverseArc(Arc a) {
432 : : Node t=target(a);
433 : : changeTarget(a,source(a));
434 : : changeSource(a,t);
435 : : }
436 : :
437 : : ///Contract two nodes.
438 : :
439 : : ///This function contracts the given two nodes.
440 : : ///Node \c v is removed, but instead of deleting its
441 : : ///incident arcs, they are joined to node \c u.
442 : : ///If the last parameter \c r is \c true (this is the default value),
443 : : ///then the newly created loops are removed.
444 : : ///
445 : : ///\note The moved arcs are joined to node \c u using changeSource()
446 : : ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
447 : : ///invalidated for the outgoing arcs of node \c v and \c InArcIt
448 : : ///iterators are invalidated for the incomming arcs of \c v.
449 : : ///Moreover all iterators referencing node \c v or the removed
450 : : ///loops are also invalidated. Other iterators remain valid.
451 : : ///
452 : : ///\warning This functionality cannot be used together with the Snapshot
453 : : ///feature.
454 : : void contract(Node u, Node v, bool r = true)
455 : : {
456 : : for(OutArcIt e(*this,v);e!=INVALID;) {
457 : : OutArcIt f=e;
458 : : ++f;
459 : : if(r && target(e)==u) erase(e);
460 : : else changeSource(e,u);
461 : : e=f;
462 : : }
463 : : for(InArcIt e(*this,v);e!=INVALID;) {
464 : : InArcIt f=e;
465 : : ++f;
466 : : if(r && source(e)==u) erase(e);
467 : : else changeTarget(e,u);
468 : : e=f;
469 : : }
470 : : erase(v);
471 : : }
472 : :
473 : : ///Split a node.
474 : :
475 : : ///This function splits the given node. First, a new node is added
476 : : ///to the digraph, then the source of each outgoing arc of node \c n
477 : : ///is moved to this new node.
478 : : ///If the second parameter \c connect is \c true (this is the default
479 : : ///value), then a new arc from node \c n to the newly created node
480 : : ///is also added.
481 : : ///\return The newly created node.
482 : : ///
483 : : ///\note All iterators remain valid.
484 : : ///
485 : : ///\warning This functionality cannot be used together with the
486 : : ///Snapshot feature.
487 : : Node split(Node n, bool connect = true) {
488 : : Node b = addNode();
489 : : nodes[b.id].first_out=nodes[n.id].first_out;
490 : : nodes[n.id].first_out=-1;
491 : : for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
492 : : arcs[i].source=b.id;
493 : : }
494 : : if (connect) addArc(n,b);
495 : : return b;
496 : : }
497 : :
498 : : ///Split an arc.
499 : :
500 : : ///This function splits the given arc. First, a new node \c v is
501 : : ///added to the digraph, then the target node of the original arc
502 : : ///is set to \c v. Finally, an arc from \c v to the original target
503 : : ///is added.
504 : : ///\return The newly created node.
505 : : ///
506 : : ///\note \c InArcIt iterators referencing the original arc are
507 : : ///invalidated. Other iterators remain valid.
508 : : ///
509 : : ///\warning This functionality cannot be used together with the
510 : : ///Snapshot feature.
511 : : Node split(Arc a) {
512 : : Node v = addNode();
513 : : addArc(v,target(a));
514 : : changeTarget(a,v);
515 : : return v;
516 : : }
517 : :
518 : : ///Clear the digraph.
519 : :
520 : : ///This function erases all nodes and arcs from the digraph.
521 : : ///
522 : : ///\note All iterators of the digraph are invalidated, of course.
523 : : void clear() {
524 : : Parent::clear();
525 : : }
526 : :
527 : : /// Reserve memory for nodes.
528 : :
529 : : /// Using this function, it is possible to avoid superfluous memory
530 : : /// allocation: if you know that the digraph you want to build will
531 : : /// be large (e.g. it will contain millions of nodes and/or arcs),
532 : : /// then it is worth reserving space for this amount before starting
533 : : /// to build the digraph.
534 : : /// \sa reserveArc()
535 : : void reserveNode(int n) { nodes.reserve(n); };
536 : :
537 : : /// Reserve memory for arcs.
538 : :
539 : : /// Using this function, it is possible to avoid superfluous memory
540 : : /// allocation: if you know that the digraph you want to build will
541 : : /// be large (e.g. it will contain millions of nodes and/or arcs),
542 : : /// then it is worth reserving space for this amount before starting
543 : : /// to build the digraph.
544 : : /// \sa reserveNode()
545 : : void reserveArc(int m) { arcs.reserve(m); };
546 : :
547 : : /// \brief Class to make a snapshot of the digraph and restore
548 : : /// it later.
549 : : ///
550 : : /// Class to make a snapshot of the digraph and restore it later.
551 : : ///
552 : : /// The newly added nodes and arcs can be removed using the
553 : : /// restore() function.
554 : : ///
555 : : /// \note After a state is restored, you cannot restore a later state,
556 : : /// i.e. you cannot add the removed nodes and arcs again using
557 : : /// another Snapshot instance.
558 : : ///
559 : : /// \warning Node and arc deletions and other modifications (e.g.
560 : : /// reversing, contracting, splitting arcs or nodes) cannot be
561 : : /// restored. These events invalidate the snapshot.
562 : : /// However, the arcs and nodes that were added to the digraph after
563 : : /// making the current snapshot can be removed without invalidating it.
564 : : class Snapshot {
565 : : protected:
566 : :
567 : : typedef Parent::NodeNotifier NodeNotifier;
568 : :
569 : : class NodeObserverProxy : public NodeNotifier::ObserverBase {
570 : : public:
571 : :
572 : : NodeObserverProxy(Snapshot& _snapshot)
573 : : : snapshot(_snapshot) {}
574 : :
575 : : using NodeNotifier::ObserverBase::attach;
576 : : using NodeNotifier::ObserverBase::detach;
577 : : using NodeNotifier::ObserverBase::attached;
578 : :
579 : : protected:
580 : :
581 : : virtual void add(const Node& node) {
582 : : snapshot.addNode(node);
583 : : }
584 : : virtual void add(const std::vector<Node>& nodes) {
585 : : for (int i = nodes.size() - 1; i >= 0; ++i) {
586 : : snapshot.addNode(nodes[i]);
587 : : }
588 : : }
589 : : virtual void erase(const Node& node) {
590 : : snapshot.eraseNode(node);
591 : : }
592 : : virtual void erase(const std::vector<Node>& nodes) {
593 : : for (int i = 0; i < int(nodes.size()); ++i) {
594 : : snapshot.eraseNode(nodes[i]);
595 : : }
596 : : }
597 : : virtual void build() {
598 : : Node node;
599 : : std::vector<Node> nodes;
600 : : for (notifier()->first(node); node != INVALID;
601 : : notifier()->next(node)) {
602 : : nodes.push_back(node);
603 : : }
604 : : for (int i = nodes.size() - 1; i >= 0; --i) {
605 : : snapshot.addNode(nodes[i]);
606 : : }
607 : : }
608 : : virtual void clear() {
609 : : Node node;
610 : : for (notifier()->first(node); node != INVALID;
611 : : notifier()->next(node)) {
612 : : snapshot.eraseNode(node);
613 : : }
614 : : }
615 : :
616 : : Snapshot& snapshot;
617 : : };
618 : :
619 : : class ArcObserverProxy : public ArcNotifier::ObserverBase {
620 : : public:
621 : :
622 : : ArcObserverProxy(Snapshot& _snapshot)
623 : : : snapshot(_snapshot) {}
624 : :
625 : : using ArcNotifier::ObserverBase::attach;
626 : : using ArcNotifier::ObserverBase::detach;
627 : : using ArcNotifier::ObserverBase::attached;
628 : :
629 : : protected:
630 : :
631 : : virtual void add(const Arc& arc) {
632 : : snapshot.addArc(arc);
633 : : }
634 : : virtual void add(const std::vector<Arc>& arcs) {
635 : : for (int i = arcs.size() - 1; i >= 0; ++i) {
636 : : snapshot.addArc(arcs[i]);
637 : : }
638 : : }
639 : : virtual void erase(const Arc& arc) {
640 : : snapshot.eraseArc(arc);
641 : : }
642 : : virtual void erase(const std::vector<Arc>& arcs) {
643 : : for (int i = 0; i < int(arcs.size()); ++i) {
644 : : snapshot.eraseArc(arcs[i]);
645 : : }
646 : : }
647 : : virtual void build() {
648 : : Arc arc;
649 : : std::vector<Arc> arcs;
650 : : for (notifier()->first(arc); arc != INVALID;
651 : : notifier()->next(arc)) {
652 : : arcs.push_back(arc);
653 : : }
654 : : for (int i = arcs.size() - 1; i >= 0; --i) {
655 : : snapshot.addArc(arcs[i]);
656 : : }
657 : : }
658 : : virtual void clear() {
659 : : Arc arc;
660 : : for (notifier()->first(arc); arc != INVALID;
661 : : notifier()->next(arc)) {
662 : : snapshot.eraseArc(arc);
663 : : }
664 : : }
665 : :
666 : : Snapshot& snapshot;
667 : : };
668 : :
669 : : ListDigraph *digraph;
670 : :
671 : : NodeObserverProxy node_observer_proxy;
672 : : ArcObserverProxy arc_observer_proxy;
673 : :
674 : : std::list<Node> added_nodes;
675 : : std::list<Arc> added_arcs;
676 : :
677 : :
678 : : void addNode(const Node& node) {
679 : : added_nodes.push_front(node);
680 : : }
681 : : void eraseNode(const Node& node) {
682 : : std::list<Node>::iterator it =
683 : : std::find(added_nodes.begin(), added_nodes.end(), node);
684 : : if (it == added_nodes.end()) {
685 : : clear();
686 : : arc_observer_proxy.detach();
687 : : throw NodeNotifier::ImmediateDetach();
688 : : } else {
689 : : added_nodes.erase(it);
690 : : }
691 : : }
692 : :
693 : : void addArc(const Arc& arc) {
694 : : added_arcs.push_front(arc);
695 : : }
696 : : void eraseArc(const Arc& arc) {
697 : : std::list<Arc>::iterator it =
698 : : std::find(added_arcs.begin(), added_arcs.end(), arc);
699 : : if (it == added_arcs.end()) {
700 : : clear();
701 : : node_observer_proxy.detach();
702 : : throw ArcNotifier::ImmediateDetach();
703 : : } else {
704 : : added_arcs.erase(it);
705 : : }
706 : : }
707 : :
708 : : void attach(ListDigraph &_digraph) {
709 : : digraph = &_digraph;
710 : : node_observer_proxy.attach(digraph->notifier(Node()));
711 : : arc_observer_proxy.attach(digraph->notifier(Arc()));
712 : : }
713 : :
714 : : void detach() {
715 : : node_observer_proxy.detach();
716 : : arc_observer_proxy.detach();
717 : : }
718 : :
719 : : bool attached() const {
720 : : return node_observer_proxy.attached();
721 : : }
722 : :
723 : : void clear() {
724 : : added_nodes.clear();
725 : : added_arcs.clear();
726 : : }
727 : :
728 : : public:
729 : :
730 : : /// \brief Default constructor.
731 : : ///
732 : : /// Default constructor.
733 : : /// You have to call save() to actually make a snapshot.
734 : : Snapshot()
735 : : : digraph(0), node_observer_proxy(*this),
736 : : arc_observer_proxy(*this) {}
737 : :
738 : : /// \brief Constructor that immediately makes a snapshot.
739 : : ///
740 : : /// This constructor immediately makes a snapshot of the given digraph.
741 : : Snapshot(ListDigraph &gr)
742 : : : node_observer_proxy(*this),
743 : : arc_observer_proxy(*this) {
744 : : attach(gr);
745 : : }
746 : :
747 : : /// \brief Make a snapshot.
748 : : ///
749 : : /// This function makes a snapshot of the given digraph.
750 : : /// It can be called more than once. In case of a repeated
751 : : /// call, the previous snapshot gets lost.
752 : : void save(ListDigraph &gr) {
753 : : if (attached()) {
754 : : detach();
755 : : clear();
756 : : }
757 : : attach(gr);
758 : : }
759 : :
760 : : /// \brief Undo the changes until the last snapshot.
761 : : ///
762 : : /// This function undos the changes until the last snapshot
763 : : /// created by save() or Snapshot(ListDigraph&).
764 : : ///
765 : : /// \warning This method invalidates the snapshot, i.e. repeated
766 : : /// restoring is not supported unless you call save() again.
767 : : void restore() {
768 : : detach();
769 : : for(std::list<Arc>::iterator it = added_arcs.begin();
770 : : it != added_arcs.end(); ++it) {
771 : : digraph->erase(*it);
772 : : }
773 : : for(std::list<Node>::iterator it = added_nodes.begin();
774 : : it != added_nodes.end(); ++it) {
775 : : digraph->erase(*it);
776 : : }
777 : : clear();
778 : : }
779 : :
780 : : /// \brief Returns \c true if the snapshot is valid.
781 : : ///
782 : : /// This function returns \c true if the snapshot is valid.
783 : : bool valid() const {
784 : : return attached();
785 : : }
786 : : };
787 : :
788 : : };
789 : :
790 : : ///@}
791 : :
792 : : class ListGraphBase {
793 : :
794 : : protected:
795 : :
796 : : struct NodeT {
797 : : int first_out;
798 : : int prev, next;
799 : : };
800 : :
801 : : struct ArcT {
802 : : int target;
803 : : int prev_out, next_out;
804 : : };
805 : :
806 : : std::vector<NodeT> nodes;
807 : :
808 : : int first_node;
809 : :
810 : : int first_free_node;
811 : :
812 : : std::vector<ArcT> arcs;
813 : :
814 : : int first_free_arc;
815 : :
816 : : public:
817 : :
818 : : typedef ListGraphBase Graph;
819 : :
820 : : class Node {
821 : : friend class ListGraphBase;
822 : : protected:
823 : :
824 : : int id;
825 : : explicit Node(int pid) { id = pid;}
826 : :
827 : : public:
828 : : Node() {}
829 : : Node (Invalid) { id = -1; }
830 : : bool operator==(const Node& node) const {return id == node.id;}
831 : : bool operator!=(const Node& node) const {return id != node.id;}
832 : : bool operator<(const Node& node) const {return id < node.id;}
833 : : };
834 : :
835 : : class Edge {
836 : : friend class ListGraphBase;
837 : : protected:
838 : :
839 : : int id;
840 : : explicit Edge(int pid) { id = pid;}
841 : :
842 : : public:
843 : : Edge() {}
844 : : Edge (Invalid) { id = -1; }
845 : : bool operator==(const Edge& edge) const {return id == edge.id;}
846 : : bool operator!=(const Edge& edge) const {return id != edge.id;}
847 : : bool operator<(const Edge& edge) const {return id < edge.id;}
848 : : };
849 : :
850 : : class Arc {
851 : : friend class ListGraphBase;
852 : : protected:
853 : :
854 : : int id;
855 : : explicit Arc(int pid) { id = pid;}
856 : :
857 : : public:
858 : : operator Edge() const {
859 : : return id != -1 ? edgeFromId(id / 2) : INVALID;
860 : : }
861 : :
862 : : Arc() {}
863 : : Arc (Invalid) { id = -1; }
864 : : bool operator==(const Arc& arc) const {return id == arc.id;}
865 : : bool operator!=(const Arc& arc) const {return id != arc.id;}
866 : : bool operator<(const Arc& arc) const {return id < arc.id;}
867 : : };
868 : :
869 : : ListGraphBase()
870 : : : nodes(), first_node(-1),
871 : : first_free_node(-1), arcs(), first_free_arc(-1) {}
872 : :
873 : :
874 : : int maxNodeId() const { return nodes.size()-1; }
875 : : int maxEdgeId() const { return arcs.size() / 2 - 1; }
876 : : int maxArcId() const { return arcs.size()-1; }
877 : :
878 : : Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
879 : : Node target(Arc e) const { return Node(arcs[e.id].target); }
880 : :
881 : : Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
882 : : Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
883 : :
884 : : static bool direction(Arc e) {
885 : : return (e.id & 1) == 1;
886 : : }
887 : :
888 : : static Arc direct(Edge e, bool d) {
889 : : return Arc(e.id * 2 + (d ? 1 : 0));
890 : : }
891 : :
892 : : void first(Node& node) const {
893 : : node.id = first_node;
894 : : }
895 : :
896 : : void next(Node& node) const {
897 : : node.id = nodes[node.id].next;
898 : : }
899 : :
900 : : void first(Arc& e) const {
901 : : int n = first_node;
902 : : while (n != -1 && nodes[n].first_out == -1) {
903 : : n = nodes[n].next;
904 : : }
905 : : e.id = (n == -1) ? -1 : nodes[n].first_out;
906 : : }
907 : :
908 : : void next(Arc& e) const {
909 : : if (arcs[e.id].next_out != -1) {
910 : : e.id = arcs[e.id].next_out;
911 : : } else {
912 : : int n = nodes[arcs[e.id ^ 1].target].next;
913 : : while(n != -1 && nodes[n].first_out == -1) {
914 : : n = nodes[n].next;
915 : : }
916 : : e.id = (n == -1) ? -1 : nodes[n].first_out;
917 : : }
918 : : }
919 : :
920 : : void first(Edge& e) const {
921 : : int n = first_node;
922 : : while (n != -1) {
923 : : e.id = nodes[n].first_out;
924 : : while ((e.id & 1) != 1) {
925 : : e.id = arcs[e.id].next_out;
926 : : }
927 : : if (e.id != -1) {
928 : : e.id /= 2;
929 : : return;
930 : : }
931 : : n = nodes[n].next;
932 : : }
933 : : e.id = -1;
934 : : }
935 : :
936 : : void next(Edge& e) const {
937 : : int n = arcs[e.id * 2].target;
938 : : e.id = arcs[(e.id * 2) | 1].next_out;
939 : : while ((e.id & 1) != 1) {
940 : : e.id = arcs[e.id].next_out;
941 : : }
942 : : if (e.id != -1) {
943 : : e.id /= 2;
944 : : return;
945 : : }
946 : : n = nodes[n].next;
947 : : while (n != -1) {
948 : : e.id = nodes[n].first_out;
949 : : while ((e.id & 1) != 1) {
950 : : e.id = arcs[e.id].next_out;
951 : : }
952 : : if (e.id != -1) {
953 : : e.id /= 2;
954 : : return;
955 : : }
956 : : n = nodes[n].next;
957 : : }
958 : : e.id = -1;
959 : : }
960 : :
961 : : void firstOut(Arc &e, const Node& v) const {
962 : : e.id = nodes[v.id].first_out;
963 : : }
964 : : void nextOut(Arc &e) const {
965 : : e.id = arcs[e.id].next_out;
966 : : }
967 : :
968 : : void firstIn(Arc &e, const Node& v) const {
969 : : e.id = ((nodes[v.id].first_out) ^ 1);
970 : : if (e.id == -2) e.id = -1;
971 : : }
972 : : void nextIn(Arc &e) const {
973 : : e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
974 : : if (e.id == -2) e.id = -1;
975 : : }
976 : :
977 : : void firstInc(Edge &e, bool& d, const Node& v) const {
978 : : int a = nodes[v.id].first_out;
979 : : if (a != -1 ) {
980 : : e.id = a / 2;
981 : : d = ((a & 1) == 1);
982 : : } else {
983 : : e.id = -1;
984 : : d = true;
985 : : }
986 : : }
987 : : void nextInc(Edge &e, bool& d) const {
988 : : int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
989 : : if (a != -1 ) {
990 : : e.id = a / 2;
991 : : d = ((a & 1) == 1);
992 : : } else {
993 : : e.id = -1;
994 : : d = true;
995 : : }
996 : : }
997 : :
998 : : static int id(Node v) { return v.id; }
999 : : static int id(Arc e) { return e.id; }
1000 : : static int id(Edge e) { return e.id; }
1001 : :
1002 : : static Node nodeFromId(int id) { return Node(id);}
1003 : : static Arc arcFromId(int id) { return Arc(id);}
1004 : : static Edge edgeFromId(int id) { return Edge(id);}
1005 : :
1006 : : bool valid(Node n) const {
1007 : : return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
1008 : : nodes[n.id].prev != -2;
1009 : : }
1010 : :
1011 : : bool valid(Arc a) const {
1012 : : return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
1013 : : arcs[a.id].prev_out != -2;
1014 : : }
1015 : :
1016 : : bool valid(Edge e) const {
1017 : : return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1018 : : arcs[2 * e.id].prev_out != -2;
1019 : : }
1020 : :
1021 : : Node addNode() {
1022 : : int n;
1023 : :
1024 : : if(first_free_node==-1) {
1025 : : n = nodes.size();
1026 : : nodes.push_back(NodeT());
1027 : : } else {
1028 : : n = first_free_node;
1029 : : first_free_node = nodes[n].next;
1030 : : }
1031 : :
1032 : : nodes[n].next = first_node;
1033 : : if (first_node != -1) nodes[first_node].prev = n;
1034 : : first_node = n;
1035 : : nodes[n].prev = -1;
1036 : :
1037 : : nodes[n].first_out = -1;
1038 : :
1039 : : return Node(n);
1040 : : }
1041 : :
1042 : : Edge addEdge(Node u, Node v) {
1043 : : int n;
1044 : :
1045 : : if (first_free_arc == -1) {
1046 : : n = arcs.size();
1047 : : arcs.push_back(ArcT());
1048 : : arcs.push_back(ArcT());
1049 : : } else {
1050 : : n = first_free_arc;
1051 : : first_free_arc = arcs[n].next_out;
1052 : : }
1053 : :
1054 : : arcs[n].target = u.id;
1055 : : arcs[n | 1].target = v.id;
1056 : :
1057 : : arcs[n].next_out = nodes[v.id].first_out;
1058 : : if (nodes[v.id].first_out != -1) {
1059 : : arcs[nodes[v.id].first_out].prev_out = n;
1060 : : }
1061 : : arcs[n].prev_out = -1;
1062 : : nodes[v.id].first_out = n;
1063 : :
1064 : : arcs[n | 1].next_out = nodes[u.id].first_out;
1065 : : if (nodes[u.id].first_out != -1) {
1066 : : arcs[nodes[u.id].first_out].prev_out = (n | 1);
1067 : : }
1068 : : arcs[n | 1].prev_out = -1;
1069 : : nodes[u.id].first_out = (n | 1);
1070 : :
1071 : : return Edge(n / 2);
1072 : : }
1073 : :
1074 : : void erase(const Node& node) {
1075 : : int n = node.id;
1076 : :
1077 : : if(nodes[n].next != -1) {
1078 : : nodes[nodes[n].next].prev = nodes[n].prev;
1079 : : }
1080 : :
1081 : : if(nodes[n].prev != -1) {
1082 : : nodes[nodes[n].prev].next = nodes[n].next;
1083 : : } else {
1084 : : first_node = nodes[n].next;
1085 : : }
1086 : :
1087 : : nodes[n].next = first_free_node;
1088 : : first_free_node = n;
1089 : : nodes[n].prev = -2;
1090 : : }
1091 : :
1092 : : void erase(const Edge& edge) {
1093 : : int n = edge.id * 2;
1094 : :
1095 : : if (arcs[n].next_out != -1) {
1096 : : arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1097 : : }
1098 : :
1099 : : if (arcs[n].prev_out != -1) {
1100 : : arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1101 : : } else {
1102 : : nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1103 : : }
1104 : :
1105 : : if (arcs[n | 1].next_out != -1) {
1106 : : arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1107 : : }
1108 : :
1109 : : if (arcs[n | 1].prev_out != -1) {
1110 : : arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1111 : : } else {
1112 : : nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1113 : : }
1114 : :
1115 : : arcs[n].next_out = first_free_arc;
1116 : : first_free_arc = n;
1117 : : arcs[n].prev_out = -2;
1118 : : arcs[n | 1].prev_out = -2;
1119 : :
1120 : : }
1121 : :
1122 : : void clear() {
1123 : : arcs.clear();
1124 : : nodes.clear();
1125 : : first_node = first_free_node = first_free_arc = -1;
1126 : : }
1127 : :
1128 : : protected:
1129 : :
1130 : : void changeV(Edge e, Node n) {
1131 : : if(arcs[2 * e.id].next_out != -1) {
1132 : : arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1133 : : }
1134 : : if(arcs[2 * e.id].prev_out != -1) {
1135 : : arcs[arcs[2 * e.id].prev_out].next_out =
1136 : : arcs[2 * e.id].next_out;
1137 : : } else {
1138 : : nodes[arcs[(2 * e.id) | 1].target].first_out =
1139 : : arcs[2 * e.id].next_out;
1140 : : }
1141 : :
1142 : : if (nodes[n.id].first_out != -1) {
1143 : : arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1144 : : }
1145 : : arcs[(2 * e.id) | 1].target = n.id;
1146 : : arcs[2 * e.id].prev_out = -1;
1147 : : arcs[2 * e.id].next_out = nodes[n.id].first_out;
1148 : : nodes[n.id].first_out = 2 * e.id;
1149 : : }
1150 : :
1151 : : void changeU(Edge e, Node n) {
1152 : : if(arcs[(2 * e.id) | 1].next_out != -1) {
1153 : : arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1154 : : arcs[(2 * e.id) | 1].prev_out;
1155 : : }
1156 : : if(arcs[(2 * e.id) | 1].prev_out != -1) {
1157 : : arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1158 : : arcs[(2 * e.id) | 1].next_out;
1159 : : } else {
1160 : : nodes[arcs[2 * e.id].target].first_out =
1161 : : arcs[(2 * e.id) | 1].next_out;
1162 : : }
1163 : :
1164 : : if (nodes[n.id].first_out != -1) {
1165 : : arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1166 : : }
1167 : : arcs[2 * e.id].target = n.id;
1168 : : arcs[(2 * e.id) | 1].prev_out = -1;
1169 : : arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1170 : : nodes[n.id].first_out = ((2 * e.id) | 1);
1171 : : }
1172 : :
1173 : : };
1174 : :
1175 : : typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1176 : :
1177 : :
1178 : : /// \addtogroup graphs
1179 : : /// @{
1180 : :
1181 : : ///A general undirected graph structure.
1182 : :
1183 : : ///\ref ListGraph is a versatile and fast undirected graph
1184 : : ///implementation based on linked lists that are stored in
1185 : : ///\c std::vector structures.
1186 : : ///
1187 : : ///This type fully conforms to the \ref concepts::Graph "Graph concept"
1188 : : ///and it also provides several useful additional functionalities.
1189 : : ///Most of its member functions and nested classes are documented
1190 : : ///only in the concept class.
1191 : : ///
1192 : : ///This class provides only linear time counting for nodes, edges and arcs.
1193 : : ///
1194 : : ///\sa concepts::Graph
1195 : : ///\sa ListDigraph
1196 : : class ListGraph : public ExtendedListGraphBase {
1197 : : typedef ExtendedListGraphBase Parent;
1198 : :
1199 : : private:
1200 : : /// Graphs are \e not copy constructible. Use GraphCopy instead.
1201 : : ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
1202 : : /// \brief Assignment of a graph to another one is \e not allowed.
1203 : : /// Use GraphCopy instead.
1204 : : void operator=(const ListGraph &) {}
1205 : : public:
1206 : : /// Constructor
1207 : :
1208 : : /// Constructor.
1209 : : ///
1210 : : ListGraph() {}
1211 : :
1212 : : typedef Parent::OutArcIt IncEdgeIt;
1213 : :
1214 : : /// \brief Add a new node to the graph.
1215 : : ///
1216 : : /// This function adds a new node to the graph.
1217 : : /// \return The new node.
1218 : : Node addNode() { return Parent::addNode(); }
1219 : :
1220 : : /// \brief Add a new edge to the graph.
1221 : : ///
1222 : : /// This function adds a new edge to the graph between nodes
1223 : : /// \c u and \c v with inherent orientation from node \c u to
1224 : : /// node \c v.
1225 : : /// \return The new edge.
1226 : : Edge addEdge(Node u, Node v) {
1227 : : return Parent::addEdge(u, v);
1228 : : }
1229 : :
1230 : : ///\brief Erase a node from the graph.
1231 : : ///
1232 : : /// This function erases the given node along with its incident arcs
1233 : : /// from the graph.
1234 : : ///
1235 : : /// \note All iterators referencing the removed node or the incident
1236 : : /// edges are invalidated, of course.
1237 : : void erase(Node n) { Parent::erase(n); }
1238 : :
1239 : : ///\brief Erase an edge from the graph.
1240 : : ///
1241 : : /// This function erases the given edge from the graph.
1242 : : ///
1243 : : /// \note All iterators referencing the removed edge are invalidated,
1244 : : /// of course.
1245 : : void erase(Edge e) { Parent::erase(e); }
1246 : : /// Node validity check
1247 : :
1248 : : /// This function gives back \c true if the given node is valid,
1249 : : /// i.e. it is a real node of the graph.
1250 : : ///
1251 : : /// \warning A removed node could become valid again if new nodes are
1252 : : /// added to the graph.
1253 : : bool valid(Node n) const { return Parent::valid(n); }
1254 : : /// Edge validity check
1255 : :
1256 : : /// This function gives back \c true if the given edge is valid,
1257 : : /// i.e. it is a real edge of the graph.
1258 : : ///
1259 : : /// \warning A removed edge could become valid again if new edges are
1260 : : /// added to the graph.
1261 : : bool valid(Edge e) const { return Parent::valid(e); }
1262 : : /// Arc validity check
1263 : :
1264 : : /// This function gives back \c true if the given arc is valid,
1265 : : /// i.e. it is a real arc of the graph.
1266 : : ///
1267 : : /// \warning A removed arc could become valid again if new edges are
1268 : : /// added to the graph.
1269 : : bool valid(Arc a) const { return Parent::valid(a); }
1270 : :
1271 : : /// \brief Change the first node of an edge.
1272 : : ///
1273 : : /// This function changes the first node of the given edge \c e to \c n.
1274 : : ///
1275 : : ///\note \c EdgeIt and \c ArcIt iterators referencing the
1276 : : ///changed edge are invalidated and all other iterators whose
1277 : : ///base node is the changed node are also invalidated.
1278 : : ///
1279 : : ///\warning This functionality cannot be used together with the
1280 : : ///Snapshot feature.
1281 : : void changeU(Edge e, Node n) {
1282 : : Parent::changeU(e,n);
1283 : : }
1284 : : /// \brief Change the second node of an edge.
1285 : : ///
1286 : : /// This function changes the second node of the given edge \c e to \c n.
1287 : : ///
1288 : : ///\note \c EdgeIt iterators referencing the changed edge remain
1289 : : ///valid, but \c ArcIt iterators referencing the changed edge and
1290 : : ///all other iterators whose base node is the changed node are also
1291 : : ///invalidated.
1292 : : ///
1293 : : ///\warning This functionality cannot be used together with the
1294 : : ///Snapshot feature.
1295 : : void changeV(Edge e, Node n) {
1296 : : Parent::changeV(e,n);
1297 : : }
1298 : :
1299 : : /// \brief Contract two nodes.
1300 : : ///
1301 : : /// This function contracts the given two nodes.
1302 : : /// Node \c b is removed, but instead of deleting
1303 : : /// its incident edges, they are joined to node \c a.
1304 : : /// If the last parameter \c r is \c true (this is the default value),
1305 : : /// then the newly created loops are removed.
1306 : : ///
1307 : : /// \note The moved edges are joined to node \c a using changeU()
1308 : : /// or changeV(), thus all edge and arc iterators whose base node is
1309 : : /// \c b are invalidated.
1310 : : /// Moreover all iterators referencing node \c b or the removed
1311 : : /// loops are also invalidated. Other iterators remain valid.
1312 : : ///
1313 : : ///\warning This functionality cannot be used together with the
1314 : : ///Snapshot feature.
1315 : : void contract(Node a, Node b, bool r = true) {
1316 : : for(IncEdgeIt e(*this, b); e!=INVALID;) {
1317 : : IncEdgeIt f = e; ++f;
1318 : : if (r && runningNode(e) == a) {
1319 : : erase(e);
1320 : : } else if (u(e) == b) {
1321 : : changeU(e, a);
1322 : : } else {
1323 : : changeV(e, a);
1324 : : }
1325 : : e = f;
1326 : : }
1327 : : erase(b);
1328 : : }
1329 : :
1330 : : ///Clear the graph.
1331 : :
1332 : : ///This function erases all nodes and arcs from the graph.
1333 : : ///
1334 : : ///\note All iterators of the graph are invalidated, of course.
1335 : : void clear() {
1336 : : Parent::clear();
1337 : : }
1338 : :
1339 : : /// Reserve memory for nodes.
1340 : :
1341 : : /// Using this function, it is possible to avoid superfluous memory
1342 : : /// allocation: if you know that the graph you want to build will
1343 : : /// be large (e.g. it will contain millions of nodes and/or edges),
1344 : : /// then it is worth reserving space for this amount before starting
1345 : : /// to build the graph.
1346 : : /// \sa reserveEdge()
1347 : : void reserveNode(int n) { nodes.reserve(n); };
1348 : :
1349 : : /// Reserve memory for edges.
1350 : :
1351 : : /// Using this function, it is possible to avoid superfluous memory
1352 : : /// allocation: if you know that the graph you want to build will
1353 : : /// be large (e.g. it will contain millions of nodes and/or edges),
1354 : : /// then it is worth reserving space for this amount before starting
1355 : : /// to build the graph.
1356 : : /// \sa reserveNode()
1357 : : void reserveEdge(int m) { arcs.reserve(2 * m); };
1358 : :
1359 : : /// \brief Class to make a snapshot of the graph and restore
1360 : : /// it later.
1361 : : ///
1362 : : /// Class to make a snapshot of the graph and restore it later.
1363 : : ///
1364 : : /// The newly added nodes and edges can be removed
1365 : : /// using the restore() function.
1366 : : ///
1367 : : /// \note After a state is restored, you cannot restore a later state,
1368 : : /// i.e. you cannot add the removed nodes and edges again using
1369 : : /// another Snapshot instance.
1370 : : ///
1371 : : /// \warning Node and edge deletions and other modifications
1372 : : /// (e.g. changing the end-nodes of edges or contracting nodes)
1373 : : /// cannot be restored. These events invalidate the snapshot.
1374 : : /// However, the edges and nodes that were added to the graph after
1375 : : /// making the current snapshot can be removed without invalidating it.
1376 : : class Snapshot {
1377 : : protected:
1378 : :
1379 : : typedef Parent::NodeNotifier NodeNotifier;
1380 : :
1381 : : class NodeObserverProxy : public NodeNotifier::ObserverBase {
1382 : : public:
1383 : :
1384 : : NodeObserverProxy(Snapshot& _snapshot)
1385 : : : snapshot(_snapshot) {}
1386 : :
1387 : : using NodeNotifier::ObserverBase::attach;
1388 : : using NodeNotifier::ObserverBase::detach;
1389 : : using NodeNotifier::ObserverBase::attached;
1390 : :
1391 : : protected:
1392 : :
1393 : : virtual void add(const Node& node) {
1394 : : snapshot.addNode(node);
1395 : : }
1396 : : virtual void add(const std::vector<Node>& nodes) {
1397 : : for (int i = nodes.size() - 1; i >= 0; ++i) {
1398 : : snapshot.addNode(nodes[i]);
1399 : : }
1400 : : }
1401 : : virtual void erase(const Node& node) {
1402 : : snapshot.eraseNode(node);
1403 : : }
1404 : : virtual void erase(const std::vector<Node>& nodes) {
1405 : : for (int i = 0; i < int(nodes.size()); ++i) {
1406 : : snapshot.eraseNode(nodes[i]);
1407 : : }
1408 : : }
1409 : : virtual void build() {
1410 : : Node node;
1411 : : std::vector<Node> nodes;
1412 : : for (notifier()->first(node); node != INVALID;
1413 : : notifier()->next(node)) {
1414 : : nodes.push_back(node);
1415 : : }
1416 : : for (int i = nodes.size() - 1; i >= 0; --i) {
1417 : : snapshot.addNode(nodes[i]);
1418 : : }
1419 : : }
1420 : : virtual void clear() {
1421 : : Node node;
1422 : : for (notifier()->first(node); node != INVALID;
1423 : : notifier()->next(node)) {
1424 : : snapshot.eraseNode(node);
1425 : : }
1426 : : }
1427 : :
1428 : : Snapshot& snapshot;
1429 : : };
1430 : :
1431 : : class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1432 : : public:
1433 : :
1434 : : EdgeObserverProxy(Snapshot& _snapshot)
1435 : : : snapshot(_snapshot) {}
1436 : :
1437 : : using EdgeNotifier::ObserverBase::attach;
1438 : : using EdgeNotifier::ObserverBase::detach;
1439 : : using EdgeNotifier::ObserverBase::attached;
1440 : :
1441 : : protected:
1442 : :
1443 : : virtual void add(const Edge& edge) {
1444 : : snapshot.addEdge(edge);
1445 : : }
1446 : : virtual void add(const std::vector<Edge>& edges) {
1447 : : for (int i = edges.size() - 1; i >= 0; ++i) {
1448 : : snapshot.addEdge(edges[i]);
1449 : : }
1450 : : }
1451 : : virtual void erase(const Edge& edge) {
1452 : : snapshot.eraseEdge(edge);
1453 : : }
1454 : : virtual void erase(const std::vector<Edge>& edges) {
1455 : : for (int i = 0; i < int(edges.size()); ++i) {
1456 : : snapshot.eraseEdge(edges[i]);
1457 : : }
1458 : : }
1459 : : virtual void build() {
1460 : : Edge edge;
1461 : : std::vector<Edge> edges;
1462 : : for (notifier()->first(edge); edge != INVALID;
1463 : : notifier()->next(edge)) {
1464 : : edges.push_back(edge);
1465 : : }
1466 : : for (int i = edges.size() - 1; i >= 0; --i) {
1467 : : snapshot.addEdge(edges[i]);
1468 : : }
1469 : : }
1470 : : virtual void clear() {
1471 : : Edge edge;
1472 : : for (notifier()->first(edge); edge != INVALID;
1473 : : notifier()->next(edge)) {
1474 : : snapshot.eraseEdge(edge);
1475 : : }
1476 : : }
1477 : :
1478 : : Snapshot& snapshot;
1479 : : };
1480 : :
1481 : : ListGraph *graph;
1482 : :
1483 : : NodeObserverProxy node_observer_proxy;
1484 : : EdgeObserverProxy edge_observer_proxy;
1485 : :
1486 : : std::list<Node> added_nodes;
1487 : : std::list<Edge> added_edges;
1488 : :
1489 : :
1490 : : void addNode(const Node& node) {
1491 : : added_nodes.push_front(node);
1492 : : }
1493 : : void eraseNode(const Node& node) {
1494 : : std::list<Node>::iterator it =
1495 : : std::find(added_nodes.begin(), added_nodes.end(), node);
1496 : : if (it == added_nodes.end()) {
1497 : : clear();
1498 : : edge_observer_proxy.detach();
1499 : : throw NodeNotifier::ImmediateDetach();
1500 : : } else {
1501 : : added_nodes.erase(it);
1502 : : }
1503 : : }
1504 : :
1505 : : void addEdge(const Edge& edge) {
1506 : : added_edges.push_front(edge);
1507 : : }
1508 : : void eraseEdge(const Edge& edge) {
1509 : : std::list<Edge>::iterator it =
1510 : : std::find(added_edges.begin(), added_edges.end(), edge);
1511 : : if (it == added_edges.end()) {
1512 : : clear();
1513 : : node_observer_proxy.detach();
1514 : : throw EdgeNotifier::ImmediateDetach();
1515 : : } else {
1516 : : added_edges.erase(it);
1517 : : }
1518 : : }
1519 : :
1520 : : void attach(ListGraph &_graph) {
1521 : : graph = &_graph;
1522 : : node_observer_proxy.attach(graph->notifier(Node()));
1523 : : edge_observer_proxy.attach(graph->notifier(Edge()));
1524 : : }
1525 : :
1526 : : void detach() {
1527 : : node_observer_proxy.detach();
1528 : : edge_observer_proxy.detach();
1529 : : }
1530 : :
1531 : : bool attached() const {
1532 : : return node_observer_proxy.attached();
1533 : : }
1534 : :
1535 : : void clear() {
1536 : : added_nodes.clear();
1537 : : added_edges.clear();
1538 : : }
1539 : :
1540 : : public:
1541 : :
1542 : : /// \brief Default constructor.
1543 : : ///
1544 : : /// Default constructor.
1545 : : /// You have to call save() to actually make a snapshot.
1546 : : Snapshot()
1547 : : : graph(0), node_observer_proxy(*this),
1548 : : edge_observer_proxy(*this) {}
1549 : :
1550 : : /// \brief Constructor that immediately makes a snapshot.
1551 : : ///
1552 : : /// This constructor immediately makes a snapshot of the given graph.
1553 : : Snapshot(ListGraph &gr)
1554 : : : node_observer_proxy(*this),
1555 : : edge_observer_proxy(*this) {
1556 : : attach(gr);
1557 : : }
1558 : :
1559 : : /// \brief Make a snapshot.
1560 : : ///
1561 : : /// This function makes a snapshot of the given graph.
1562 : : /// It can be called more than once. In case of a repeated
1563 : : /// call, the previous snapshot gets lost.
1564 : : void save(ListGraph &gr) {
1565 : : if (attached()) {
1566 : : detach();
1567 : : clear();
1568 : : }
1569 : : attach(gr);
1570 : : }
1571 : :
1572 : : /// \brief Undo the changes until the last snapshot.
1573 : : ///
1574 : : /// This function undos the changes until the last snapshot
1575 : : /// created by save() or Snapshot(ListGraph&).
1576 : : ///
1577 : : /// \warning This method invalidates the snapshot, i.e. repeated
1578 : : /// restoring is not supported unless you call save() again.
1579 : : void restore() {
1580 : : detach();
1581 : : for(std::list<Edge>::iterator it = added_edges.begin();
1582 : : it != added_edges.end(); ++it) {
1583 : : graph->erase(*it);
1584 : : }
1585 : : for(std::list<Node>::iterator it = added_nodes.begin();
1586 : : it != added_nodes.end(); ++it) {
1587 : : graph->erase(*it);
1588 : : }
1589 : : clear();
1590 : : }
1591 : :
1592 : : /// \brief Returns \c true if the snapshot is valid.
1593 : : ///
1594 : : /// This function returns \c true if the snapshot is valid.
1595 : : bool valid() const {
1596 : : return attached();
1597 : : }
1598 : : };
1599 : : };
1600 : :
1601 : : /// @}
1602 : : } //namespace lemon
1603 : :
1604 : :
1605 : : #endif
|