gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 1 0
merge default
1 file changed with 30 insertions and 64 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -302,217 +302,217 @@
302 302
      nodes[n.id].first_out = e.id;
303 303
    }
304 304

	
305 305
  };
306 306

	
307 307
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
308 308

	
309 309
  /// \addtogroup graphs
310 310
  /// @{
311 311

	
312 312
  ///A general directed graph structure.
313 313

	
314 314
  ///\ref ListDigraph is a simple and fast <em>directed graph</em>
315 315
  ///implementation based on static linked lists that are stored in
316 316
  ///\c std::vector structures.
317 317
  ///
318 318
  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
319 319
  ///also provides several useful additional functionalities.
320 320
  ///Most of the member functions and nested classes are documented
321 321
  ///only in the concept class.
322 322
  ///
323 323
  ///An important extra feature of this digraph implementation is that
324 324
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
325 325
  ///
326 326
  ///\sa concepts::Digraph
327 327

	
328 328
  class ListDigraph : public ExtendedListDigraphBase {
329 329
  private:
330 330
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
331 331

	
332 332
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
333 333
    ///
334 334
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
335 335
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
336 336
    ///Use copyDigraph() instead.
337 337

	
338 338
    ///Assignment of ListDigraph to another one is \e not allowed.
339 339
    ///Use copyDigraph() instead.
340 340
    void operator=(const ListDigraph &) {}
341 341
  public:
342 342

	
343 343
    typedef ExtendedListDigraphBase Parent;
344 344

	
345 345
    /// Constructor
346 346

	
347 347
    /// Constructor.
348 348
    ///
349 349
    ListDigraph() {}
350 350

	
351 351
    ///Add a new node to the digraph.
352 352

	
353 353
    ///Add a new node to the digraph.
354 354
    ///\return the new node.
355 355
    Node addNode() { return Parent::addNode(); }
356 356

	
357 357
    ///Add a new arc to the digraph.
358 358

	
359 359
    ///Add a new arc to the digraph with source node \c s
360 360
    ///and target node \c t.
361 361
    ///\return the new arc.
362 362
    Arc addArc(const Node& s, const Node& t) {
363 363
      return Parent::addArc(s, t);
364 364
    }
365 365

	
366 366
    ///\brief Erase a node from the digraph.
367 367
    ///
368 368
    ///Erase a node from the digraph.
369 369
    ///
370 370
    void erase(const Node& n) { Parent::erase(n); }
371 371

	
372 372
    ///\brief Erase an arc from the digraph.
373 373
    ///
374 374
    ///Erase an arc from the digraph.
375 375
    ///
376 376
    void erase(const Arc& a) { Parent::erase(a); }
377 377

	
378 378
    /// Node validity check
379 379

	
380 380
    /// This function gives back true if the given node is valid,
381 381
    /// ie. it is a real node of the graph.
382 382
    ///
383 383
    /// \warning A Node pointing to a removed item
384 384
    /// could become valid again later if new nodes are
385 385
    /// added to the graph.
386 386
    bool valid(Node n) const { return Parent::valid(n); }
387 387

	
388 388
    /// Arc validity check
389 389

	
390 390
    /// This function gives back true if the given arc is valid,
391 391
    /// ie. it is a real arc of the graph.
392 392
    ///
393 393
    /// \warning An Arc pointing to a removed item
394 394
    /// could become valid again later if new nodes are
395 395
    /// added to the graph.
396 396
    bool valid(Arc a) const { return Parent::valid(a); }
397 397

	
398
    /// Change the target of \c e to \c n
398
    /// Change the target of \c a to \c n
399 399

	
400
    /// Change the target of \c e to \c n
400
    /// Change the target of \c a to \c n
401 401
    ///
402 402
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
403 403
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
404 404
    ///invalidated.
405 405
    ///
406 406
    ///\warning This functionality cannot be used together with the Snapshot
407 407
    ///feature.
408
    void changeTarget(Arc e, Node n) {
409
      Parent::changeTarget(e,n);
408
    void changeTarget(Arc a, Node n) {
409
      Parent::changeTarget(a,n);
410 410
    }
411
    /// Change the source of \c e to \c n
411
    /// Change the source of \c a to \c n
412 412

	
413
    /// Change the source of \c e to \c n
413
    /// Change the source of \c a to \c n
414 414
    ///
415
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
416
    ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
415
    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
416
    ///valid. However the <tt>ArcIt<tt>s and <tt>OutArcIt</tt>s are
417 417
    ///invalidated.
418 418
    ///
419 419
    ///\warning This functionality cannot be used together with the Snapshot
420 420
    ///feature.
421
    void changeSource(Arc e, Node n) {
422
      Parent::changeSource(e,n);
421
    void changeSource(Arc a, Node n) {
422
      Parent::changeSource(a,n);
423 423
    }
424 424

	
425 425
    /// Invert the direction of an arc.
426 426

	
427 427
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
428 428
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
429 429
    ///invalidated.
430 430
    ///
431 431
    ///\warning This functionality cannot be used together with the Snapshot
432 432
    ///feature.
433 433
    void reverseArc(Arc e) {
434 434
      Node t=target(e);
435 435
      changeTarget(e,source(e));
436 436
      changeSource(e,t);
437 437
    }
438 438

	
439 439
    /// Reserve memory for nodes.
440 440

	
441 441
    /// Using this function it is possible to avoid the superfluous memory
442 442
    /// allocation: if you know that the digraph you want to build will
443 443
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
444 444
    /// then it is worth reserving space for this amount before starting
445 445
    /// to build the digraph.
446 446
    /// \sa reserveArc
447 447
    void reserveNode(int n) { nodes.reserve(n); };
448 448

	
449 449
    /// Reserve memory for arcs.
450 450

	
451 451
    /// Using this function it is possible to avoid the superfluous memory
452 452
    /// allocation: if you know that the digraph you want to build will
453 453
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
454 454
    /// then it is worth reserving space for this amount before starting
455 455
    /// to build the digraph.
456 456
    /// \sa reserveNode
457 457
    void reserveArc(int m) { arcs.reserve(m); };
458 458

	
459 459
    ///Contract two nodes.
460 460

	
461 461
    ///This function contracts two nodes.
462 462
    ///Node \p b will be removed but instead of deleting
463 463
    ///incident arcs, they will be joined to \p a.
464 464
    ///The last parameter \p r controls whether to remove loops. \c true
465 465
    ///means that loops will be removed.
466 466
    ///
467 467
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
468 468
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
469 469
    ///may be invalidated.
470 470
    ///
471 471
    ///\warning This functionality cannot be used together with the Snapshot
472 472
    ///feature.
473 473
    void contract(Node a, Node b, bool r = true)
474 474
    {
475 475
      for(OutArcIt e(*this,b);e!=INVALID;) {
476 476
        OutArcIt f=e;
477 477
        ++f;
478 478
        if(r && target(e)==a) erase(e);
479 479
        else changeSource(e,a);
480 480
        e=f;
481 481
      }
482 482
      for(InArcIt e(*this,b);e!=INVALID;) {
483 483
        InArcIt f=e;
484 484
        ++f;
485 485
        if(r && source(e)==a) erase(e);
486 486
        else changeTarget(e,a);
487 487
        e=f;
488 488
      }
489 489
      erase(b);
490 490
    }
491 491

	
492 492
    ///Split a node.
493 493

	
494 494
    ///This function splits a node. First a new node is added to the digraph,
495 495
    ///then the source of each outgoing arc of \c n is moved to this new node.
496 496
    ///If \c connect is \c true (this is the default value), then a new arc
497 497
    ///from \c n to the newly created node is also added.
498 498
    ///\return The newly created node.
499 499
    ///
500 500
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
501 501
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
502 502
    ///be invalidated.
503 503
    ///
504 504
    ///\warning This functionality cannot be used together with the
505 505
    ///Snapshot feature.
506 506
    ///
507 507
    ///\todo It could be implemented in a bit faster way.
508 508
    Node split(Node n, bool connect = true) {
509 509
      Node b = addNode();
510 510
      for(OutArcIt e(*this,n);e!=INVALID;) {
511 511
        OutArcIt f=e;
512 512
        ++f;
513 513
        changeSource(e,b);
514 514
        e=f;
515 515
      }
516 516
      if (connect) addArc(n,b);
517 517
      return b;
518 518
    }
... ...
@@ -1023,419 +1023,385 @@
1023 1023
      first_node = n;
1024 1024
      nodes[n].prev = -1;
1025 1025

	
1026 1026
      nodes[n].first_out = -1;
1027 1027

	
1028 1028
      return Node(n);
1029 1029
    }
1030 1030

	
1031 1031
    Edge addEdge(Node u, Node v) {
1032 1032
      int n;
1033 1033

	
1034 1034
      if (first_free_arc == -1) {
1035 1035
        n = arcs.size();
1036 1036
        arcs.push_back(ArcT());
1037 1037
        arcs.push_back(ArcT());
1038 1038
      } else {
1039 1039
        n = first_free_arc;
1040 1040
        first_free_arc = arcs[n].next_out;
1041 1041
      }
1042 1042

	
1043 1043
      arcs[n].target = u.id;
1044 1044
      arcs[n | 1].target = v.id;
1045 1045

	
1046 1046
      arcs[n].next_out = nodes[v.id].first_out;
1047 1047
      if (nodes[v.id].first_out != -1) {
1048 1048
        arcs[nodes[v.id].first_out].prev_out = n;
1049 1049
      }
1050 1050
      arcs[n].prev_out = -1;
1051 1051
      nodes[v.id].first_out = n;
1052 1052

	
1053 1053
      arcs[n | 1].next_out = nodes[u.id].first_out;
1054 1054
      if (nodes[u.id].first_out != -1) {
1055 1055
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
1056 1056
      }
1057 1057
      arcs[n | 1].prev_out = -1;
1058 1058
      nodes[u.id].first_out = (n | 1);
1059 1059

	
1060 1060
      return Edge(n / 2);
1061 1061
    }
1062 1062

	
1063 1063
    void erase(const Node& node) {
1064 1064
      int n = node.id;
1065 1065

	
1066 1066
      if(nodes[n].next != -1) {
1067 1067
        nodes[nodes[n].next].prev = nodes[n].prev;
1068 1068
      }
1069 1069

	
1070 1070
      if(nodes[n].prev != -1) {
1071 1071
        nodes[nodes[n].prev].next = nodes[n].next;
1072 1072
      } else {
1073 1073
        first_node = nodes[n].next;
1074 1074
      }
1075 1075

	
1076 1076
      nodes[n].next = first_free_node;
1077 1077
      first_free_node = n;
1078 1078
      nodes[n].prev = -2;
1079 1079
    }
1080 1080

	
1081 1081
    void erase(const Edge& edge) {
1082 1082
      int n = edge.id * 2;
1083 1083

	
1084 1084
      if (arcs[n].next_out != -1) {
1085 1085
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1086 1086
      }
1087 1087

	
1088 1088
      if (arcs[n].prev_out != -1) {
1089 1089
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1090 1090
      } else {
1091 1091
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1092 1092
      }
1093 1093

	
1094 1094
      if (arcs[n | 1].next_out != -1) {
1095 1095
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1096 1096
      }
1097 1097

	
1098 1098
      if (arcs[n | 1].prev_out != -1) {
1099 1099
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1100 1100
      } else {
1101 1101
        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1102 1102
      }
1103 1103

	
1104 1104
      arcs[n].next_out = first_free_arc;
1105 1105
      first_free_arc = n;
1106 1106
      arcs[n].prev_out = -2;
1107 1107
      arcs[n | 1].prev_out = -2;
1108 1108

	
1109 1109
    }
1110 1110

	
1111 1111
    void clear() {
1112 1112
      arcs.clear();
1113 1113
      nodes.clear();
1114 1114
      first_node = first_free_node = first_free_arc = -1;
1115 1115
    }
1116 1116

	
1117 1117
  protected:
1118 1118

	
1119
    void changeTarget(Edge e, Node n) {
1119
    void changeV(Edge e, Node n) {
1120 1120
      if(arcs[2 * e.id].next_out != -1) {
1121 1121
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1122 1122
      }
1123 1123
      if(arcs[2 * e.id].prev_out != -1) {
1124 1124
        arcs[arcs[2 * e.id].prev_out].next_out =
1125 1125
          arcs[2 * e.id].next_out;
1126 1126
      } else {
1127 1127
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1128 1128
          arcs[2 * e.id].next_out;
1129 1129
      }
1130 1130

	
1131 1131
      if (nodes[n.id].first_out != -1) {
1132 1132
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1133 1133
      }
1134 1134
      arcs[(2 * e.id) | 1].target = n.id;
1135 1135
      arcs[2 * e.id].prev_out = -1;
1136 1136
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1137 1137
      nodes[n.id].first_out = 2 * e.id;
1138 1138
    }
1139 1139

	
1140
    void changeSource(Edge e, Node n) {
1140
    void changeU(Edge e, Node n) {
1141 1141
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1142 1142
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1143 1143
          arcs[(2 * e.id) | 1].prev_out;
1144 1144
      }
1145 1145
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1146 1146
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1147 1147
          arcs[(2 * e.id) | 1].next_out;
1148 1148
      } else {
1149 1149
        nodes[arcs[2 * e.id].target].first_out =
1150 1150
          arcs[(2 * e.id) | 1].next_out;
1151 1151
      }
1152 1152

	
1153 1153
      if (nodes[n.id].first_out != -1) {
1154 1154
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1155 1155
      }
1156 1156
      arcs[2 * e.id].target = n.id;
1157 1157
      arcs[(2 * e.id) | 1].prev_out = -1;
1158 1158
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1159 1159
      nodes[n.id].first_out = ((2 * e.id) | 1);
1160 1160
    }
1161 1161

	
1162 1162
  };
1163 1163

	
1164 1164
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1165 1165

	
1166 1166

	
1167 1167
  /// \addtogroup graphs
1168 1168
  /// @{
1169 1169

	
1170 1170
  ///A general undirected graph structure.
1171 1171

	
1172 1172
  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1173 1173
  ///implementation based on static linked lists that are stored in
1174 1174
  ///\c std::vector structures.
1175 1175
  ///
1176 1176
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1177 1177
  ///also provides several useful additional functionalities.
1178 1178
  ///Most of the member functions and nested classes are documented
1179 1179
  ///only in the concept class.
1180 1180
  ///
1181 1181
  ///An important extra feature of this graph implementation is that
1182 1182
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1183 1183
  ///
1184 1184
  ///\sa concepts::Graph
1185 1185

	
1186 1186
  class ListGraph : public ExtendedListGraphBase {
1187 1187
  private:
1188 1188
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1189 1189

	
1190 1190
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1191 1191
    ///
1192 1192
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1193 1193
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1194 1194
    ///Use copyGraph() instead.
1195 1195

	
1196 1196
    ///Assignment of ListGraph to another one is \e not allowed.
1197 1197
    ///Use copyGraph() instead.
1198 1198
    void operator=(const ListGraph &) {}
1199 1199
  public:
1200 1200
    /// Constructor
1201 1201

	
1202 1202
    /// Constructor.
1203 1203
    ///
1204 1204
    ListGraph() {}
1205 1205

	
1206 1206
    typedef ExtendedListGraphBase Parent;
1207 1207

	
1208 1208
    typedef Parent::OutArcIt IncEdgeIt;
1209 1209

	
1210 1210
    /// \brief Add a new node to the graph.
1211 1211
    ///
1212 1212
    /// Add a new node to the graph.
1213 1213
    /// \return the new node.
1214 1214
    Node addNode() { return Parent::addNode(); }
1215 1215

	
1216 1216
    /// \brief Add a new edge to the graph.
1217 1217
    ///
1218 1218
    /// Add a new edge to the graph with source node \c s
1219 1219
    /// and target node \c t.
1220 1220
    /// \return the new edge.
1221 1221
    Edge addEdge(const Node& s, const Node& t) {
1222 1222
      return Parent::addEdge(s, t);
1223 1223
    }
1224 1224

	
1225 1225
    /// \brief Erase a node from the graph.
1226 1226
    ///
1227 1227
    /// Erase a node from the graph.
1228 1228
    ///
1229 1229
    void erase(const Node& n) { Parent::erase(n); }
1230 1230

	
1231 1231
    /// \brief Erase an edge from the graph.
1232 1232
    ///
1233 1233
    /// Erase an edge from the graph.
1234 1234
    ///
1235 1235
    void erase(const Edge& e) { Parent::erase(e); }
1236 1236
    /// Node validity check
1237 1237

	
1238 1238
    /// This function gives back true if the given node is valid,
1239 1239
    /// ie. it is a real node of the graph.
1240 1240
    ///
1241 1241
    /// \warning A Node pointing to a removed item
1242 1242
    /// could become valid again later if new nodes are
1243 1243
    /// added to the graph.
1244 1244
    bool valid(Node n) const { return Parent::valid(n); }
1245 1245
    /// Arc validity check
1246 1246

	
1247 1247
    /// This function gives back true if the given arc is valid,
1248 1248
    /// ie. it is a real arc of the graph.
1249 1249
    ///
1250 1250
    /// \warning An Arc pointing to a removed item
1251 1251
    /// could become valid again later if new edges are
1252 1252
    /// added to the graph.
1253 1253
    bool valid(Arc a) const { return Parent::valid(a); }
1254 1254
    /// Edge validity check
1255 1255

	
1256 1256
    /// This function gives back true if the given edge is valid,
1257 1257
    /// ie. it is a real arc of the graph.
1258 1258
    ///
1259 1259
    /// \warning A Edge pointing to a removed item
1260 1260
    /// could become valid again later if new edges are
1261 1261
    /// added to the graph.
1262 1262
    bool valid(Edge e) const { return Parent::valid(e); }
1263
    /// \brief Change the source of \c e to \c n
1263
    /// \brief Change the end \c u of \c e to \c n
1264 1264
    ///
1265
    /// This function changes the source of \c e to \c n.
1265
    /// This function changes the end \c u of \c e to node \c n.
1266 1266
    ///
1267
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1268
    ///referencing the changed arc remain
1269
    ///valid. However <tt>OutArcIt</tt>s are invalidated.
1267
    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
1268
    ///changed edge are invalidated and if the changed node is the
1269
    ///base node of an iterator then this iterator is also
1270
    ///invalidated.
1270 1271
    ///
1271 1272
    ///\warning This functionality cannot be used together with the
1272 1273
    ///Snapshot feature.
1273
    void changeSource(Edge e, Node n) {
1274
      Parent::changeSource(e,n);
1274
    void changeU(Edge e, Node n) {
1275
      Parent::changeU(e,n);
1275 1276
    }
1276
    /// \brief Change the target of \c e to \c n
1277
    /// \brief Change the end \c v of \c e to \c n
1277 1278
    ///
1278
    /// This function changes the target of \c e to \c n.
1279
    /// This function changes the end \c v of \c e to \c n.
1279 1280
    ///
1280
    /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
1281
    /// valid. However the other iterators may be invalidated.
1281
    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
1282
    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
1283
    ///base node of an iterator then this iterator is invalidated.
1282 1284
    ///
1283 1285
    ///\warning This functionality cannot be used together with the
1284 1286
    ///Snapshot feature.
1285
    void changeTarget(Edge e, Node n) {
1286
      Parent::changeTarget(e,n);
1287
    }
1288
    /// \brief Change the source of \c e to \c n
1289
    ///
1290
    /// This function changes the source of \c e to \c n.
1291
    /// It also changes the proper node of the represented edge.
1292
    ///
1293
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1294
    ///referencing the changed arc remain
1295
    ///valid. However <tt>OutArcIt</tt>s are invalidated.
1296
    ///
1297
    ///\warning This functionality cannot be used together with the
1298
    ///Snapshot feature.
1299
    void changeSource(Arc e, Node n) {
1300
      if (Parent::direction(e)) {
1301
        Parent::changeSource(e,n);
1302
      } else {
1303
        Parent::changeTarget(e,n);
1304
      }
1305
    }
1306
    /// \brief Change the target of \c e to \c n
1307
    ///
1308
    /// This function changes the target of \c e to \c n.
1309
    /// It also changes the proper node of the represented edge.
1310
    ///
1311
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s
1312
    ///referencing the changed arc remain
1313
    ///valid. However <tt>InArcIt</tt>s are invalidated.
1314
    ///
1315
    ///\warning This functionality cannot be used together with the
1316
    ///Snapshot feature.
1317
    void changeTarget(Arc e, Node n) {
1318
      if (Parent::direction(e)) {
1319
        Parent::changeTarget(e,n);
1320
      } else {
1321
        Parent::changeSource(e,n);
1322
      }
1287
    void changeV(Edge e, Node n) {
1288
      Parent::changeV(e,n);
1323 1289
    }
1324 1290
    /// \brief Contract two nodes.
1325 1291
    ///
1326 1292
    /// This function contracts two nodes.
1327 1293
    /// Node \p b will be removed but instead of deleting
1328 1294
    /// its neighboring arcs, they will be joined to \p a.
1329 1295
    /// The last parameter \p r controls whether to remove loops. \c true
1330 1296
    /// means that loops will be removed.
1331 1297
    ///
1332 1298
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1333 1299
    /// valid.
1334 1300
    ///
1335 1301
    ///\warning This functionality cannot be used together with the
1336 1302
    ///Snapshot feature.
1337 1303
    void contract(Node a, Node b, bool r = true) {
1338 1304
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1339 1305
        IncEdgeIt f = e; ++f;
1340 1306
        if (r && runningNode(e) == a) {
1341 1307
          erase(e);
1342
        } else if (source(e) == b) {
1343
          changeSource(e, a);
1308
        } else if (u(e) == b) {
1309
          changeU(e, a);
1344 1310
        } else {
1345
          changeTarget(e, a);
1311
          changeV(e, a);
1346 1312
        }
1347 1313
        e = f;
1348 1314
      }
1349 1315
      erase(b);
1350 1316
    }
1351 1317

	
1352 1318

	
1353 1319
    /// \brief Class to make a snapshot of the graph and restore
1354 1320
    /// it later.
1355 1321
    ///
1356 1322
    /// Class to make a snapshot of the graph and restore it later.
1357 1323
    ///
1358 1324
    /// The newly added nodes and edges can be removed
1359 1325
    /// using the restore() function.
1360 1326
    ///
1361 1327
    /// \warning Edge and node deletions and other modifications
1362 1328
    /// (e.g. changing nodes of edges, contracting nodes) cannot be
1363 1329
    /// restored. These events invalidate the snapshot.
1364 1330
    class Snapshot {
1365 1331
    protected:
1366 1332

	
1367 1333
      typedef Parent::NodeNotifier NodeNotifier;
1368 1334

	
1369 1335
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1370 1336
      public:
1371 1337

	
1372 1338
        NodeObserverProxy(Snapshot& _snapshot)
1373 1339
          : snapshot(_snapshot) {}
1374 1340

	
1375 1341
        using NodeNotifier::ObserverBase::attach;
1376 1342
        using NodeNotifier::ObserverBase::detach;
1377 1343
        using NodeNotifier::ObserverBase::attached;
1378 1344

	
1379 1345
      protected:
1380 1346

	
1381 1347
        virtual void add(const Node& node) {
1382 1348
          snapshot.addNode(node);
1383 1349
        }
1384 1350
        virtual void add(const std::vector<Node>& nodes) {
1385 1351
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1386 1352
            snapshot.addNode(nodes[i]);
1387 1353
          }
1388 1354
        }
1389 1355
        virtual void erase(const Node& node) {
1390 1356
          snapshot.eraseNode(node);
1391 1357
        }
1392 1358
        virtual void erase(const std::vector<Node>& nodes) {
1393 1359
          for (int i = 0; i < int(nodes.size()); ++i) {
1394 1360
            snapshot.eraseNode(nodes[i]);
1395 1361
          }
1396 1362
        }
1397 1363
        virtual void build() {
1398 1364
          Node node;
1399 1365
          std::vector<Node> nodes;
1400 1366
          for (notifier()->first(node); node != INVALID;
1401 1367
               notifier()->next(node)) {
1402 1368
            nodes.push_back(node);
1403 1369
          }
1404 1370
          for (int i = nodes.size() - 1; i >= 0; --i) {
1405 1371
            snapshot.addNode(nodes[i]);
1406 1372
          }
1407 1373
        }
1408 1374
        virtual void clear() {
1409 1375
          Node node;
1410 1376
          for (notifier()->first(node); node != INVALID;
1411 1377
               notifier()->next(node)) {
1412 1378
            snapshot.eraseNode(node);
1413 1379
          }
1414 1380
        }
1415 1381

	
1416 1382
        Snapshot& snapshot;
1417 1383
      };
1418 1384

	
1419 1385
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1420 1386
      public:
1421 1387

	
1422 1388
        EdgeObserverProxy(Snapshot& _snapshot)
1423 1389
          : snapshot(_snapshot) {}
1424 1390

	
1425 1391
        using EdgeNotifier::ObserverBase::attach;
1426 1392
        using EdgeNotifier::ObserverBase::detach;
1427 1393
        using EdgeNotifier::ObserverBase::attached;
1428 1394

	
1429 1395
      protected:
1430 1396

	
1431 1397
        virtual void add(const Edge& edge) {
1432 1398
          snapshot.addEdge(edge);
1433 1399
        }
1434 1400
        virtual void add(const std::vector<Edge>& edges) {
1435 1401
          for (int i = edges.size() - 1; i >= 0; ++i) {
1436 1402
            snapshot.addEdge(edges[i]);
1437 1403
          }
1438 1404
        }
1439 1405
        virtual void erase(const Edge& edge) {
1440 1406
          snapshot.eraseEdge(edge);
1441 1407
        }
0 comments (0 inline)