gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge #180 and a bugfix in #51
0 6 2
merge default
1 file changed with 3052 insertions and 49 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
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-2009
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_PLANARITY_H
20
#define LEMON_PLANARITY_H
21

	
22
/// \ingroup planar
23
/// \file
24
/// \brief Planarity checking, embedding, drawing and coloring
25

	
26
#include <vector>
27
#include <list>
28

	
29
#include <lemon/dfs.h>
30
#include <lemon/bfs.h>
31
#include <lemon/radix_sort.h>
32
#include <lemon/maps.h>
33
#include <lemon/path.h>
34
#include <lemon/bucket_heap.h>
35
#include <lemon/adaptors.h>
36
#include <lemon/edge_set.h>
37
#include <lemon/color.h>
38
#include <lemon/dim2.h>
39

	
40
namespace lemon {
41

	
42
  namespace _planarity_bits {
43

	
44
    template <typename Graph>
45
    struct PlanarityVisitor : DfsVisitor<Graph> {
46

	
47
      TEMPLATE_GRAPH_TYPEDEFS(Graph);
48

	
49
      typedef typename Graph::template NodeMap<Arc> PredMap;
50

	
51
      typedef typename Graph::template EdgeMap<bool> TreeMap;
52

	
53
      typedef typename Graph::template NodeMap<int> OrderMap;
54
      typedef std::vector<Node> OrderList;
55

	
56
      typedef typename Graph::template NodeMap<int> LowMap;
57
      typedef typename Graph::template NodeMap<int> AncestorMap;
58

	
59
      PlanarityVisitor(const Graph& graph,
60
                       PredMap& pred_map, TreeMap& tree_map,
61
                       OrderMap& order_map, OrderList& order_list,
62
                       AncestorMap& ancestor_map, LowMap& low_map)
63
        : _graph(graph), _pred_map(pred_map), _tree_map(tree_map),
64
          _order_map(order_map), _order_list(order_list),
65
          _ancestor_map(ancestor_map), _low_map(low_map) {}
66

	
67
      void reach(const Node& node) {
68
        _order_map[node] = _order_list.size();
69
        _low_map[node] = _order_list.size();
70
        _ancestor_map[node] = _order_list.size();
71
        _order_list.push_back(node);
72
      }
73

	
74
      void discover(const Arc& arc) {
75
        Node source = _graph.source(arc);
76
        Node target = _graph.target(arc);
77

	
78
        _tree_map[arc] = true;
79
        _pred_map[target] = arc;
80
      }
81

	
82
      void examine(const Arc& arc) {
83
        Node source = _graph.source(arc);
84
        Node target = _graph.target(arc);
85

	
86
        if (_order_map[target] < _order_map[source] && !_tree_map[arc]) {
87
          if (_low_map[source] > _order_map[target]) {
88
            _low_map[source] = _order_map[target];
89
          }
90
          if (_ancestor_map[source] > _order_map[target]) {
91
            _ancestor_map[source] = _order_map[target];
92
          }
93
        }
94
      }
95

	
96
      void backtrack(const Arc& arc) {
97
        Node source = _graph.source(arc);
98
        Node target = _graph.target(arc);
99

	
100
        if (_low_map[source] > _low_map[target]) {
101
          _low_map[source] = _low_map[target];
102
        }
103
      }
104

	
105
      const Graph& _graph;
106
      PredMap& _pred_map;
107
      TreeMap& _tree_map;
108
      OrderMap& _order_map;
109
      OrderList& _order_list;
110
      AncestorMap& _ancestor_map;
111
      LowMap& _low_map;
112
    };
113

	
114
    template <typename Graph, bool embedding = true>
115
    struct NodeDataNode {
116
      int prev, next;
117
      int visited;
118
      typename Graph::Arc first;
119
      bool inverted;
120
    };
121

	
122
    template <typename Graph>
123
    struct NodeDataNode<Graph, false> {
124
      int prev, next;
125
      int visited;
126
    };
127

	
128
    template <typename Graph>
129
    struct ChildListNode {
130
      typedef typename Graph::Node Node;
131
      Node first;
132
      Node prev, next;
133
    };
134

	
135
    template <typename Graph>
136
    struct ArcListNode {
137
      typename Graph::Arc prev, next;
138
    };
139

	
140
    template <typename Graph>
141
    class PlanarityChecking {
142
    private:
143
      
144
      TEMPLATE_GRAPH_TYPEDEFS(Graph);
145

	
146
      const Graph& _graph;
147

	
148
    private:
149
      
150
      typedef typename Graph::template NodeMap<Arc> PredMap;
151
      
152
      typedef typename Graph::template EdgeMap<bool> TreeMap;
153
      
154
      typedef typename Graph::template NodeMap<int> OrderMap;
155
      typedef std::vector<Node> OrderList;
156

	
157
      typedef typename Graph::template NodeMap<int> LowMap;
158
      typedef typename Graph::template NodeMap<int> AncestorMap;
159

	
160
      typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
161
      typedef std::vector<NodeDataNode> NodeData;
162

	
163
      typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
164
      typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
165

	
166
      typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
167

	
168
      typedef typename Graph::template NodeMap<bool> EmbedArc;
169

	
170
    public:
171

	
172
      PlanarityChecking(const Graph& graph) : _graph(graph) {}
173

	
174
      bool run() {
175
        typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
176

	
177
        PredMap pred_map(_graph, INVALID);
178
        TreeMap tree_map(_graph, false);
179

	
180
        OrderMap order_map(_graph, -1);
181
        OrderList order_list;
182

	
183
        AncestorMap ancestor_map(_graph, -1);
184
        LowMap low_map(_graph, -1);
185

	
186
        Visitor visitor(_graph, pred_map, tree_map,
187
                        order_map, order_list, ancestor_map, low_map);
188
        DfsVisit<Graph, Visitor> visit(_graph, visitor);
189
        visit.run();
190

	
191
        ChildLists child_lists(_graph);
192
        createChildLists(tree_map, order_map, low_map, child_lists);
193

	
194
        NodeData node_data(2 * order_list.size());
195

	
196
        EmbedArc embed_arc(_graph, false);
197

	
198
        MergeRoots merge_roots(_graph);
199

	
200
        for (int i = order_list.size() - 1; i >= 0; --i) {
201

	
202
          Node node = order_list[i];
203

	
204
          Node source = node;
205
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
206
            Node target = _graph.target(e);
207

	
208
            if (order_map[source] < order_map[target] && tree_map[e]) {
209
              initFace(target, node_data, order_map, order_list);
210
            }
211
          }
212

	
213
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
214
            Node target = _graph.target(e);
215

	
216
            if (order_map[source] < order_map[target] && !tree_map[e]) {
217
              embed_arc[target] = true;
218
              walkUp(target, source, i, pred_map, low_map,
219
                     order_map, order_list, node_data, merge_roots);
220
            }
221
          }
222

	
223
          for (typename MergeRoots::Value::iterator it =
224
                 merge_roots[node].begin(); 
225
               it != merge_roots[node].end(); ++it) {
226
            int rn = *it;
227
            walkDown(rn, i, node_data, order_list, child_lists,
228
                     ancestor_map, low_map, embed_arc, merge_roots);
229
          }
230
          merge_roots[node].clear();
231

	
232
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
233
            Node target = _graph.target(e);
234

	
235
            if (order_map[source] < order_map[target] && !tree_map[e]) {
236
              if (embed_arc[target]) {
237
                return false;
238
              }
239
            }
240
          }
241
        }
242

	
243
        return true;
244
      }
245

	
246
    private:
247

	
248
      void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
249
                            const LowMap& low_map, ChildLists& child_lists) {
250

	
251
        for (NodeIt n(_graph); n != INVALID; ++n) {
252
          Node source = n;
253

	
254
          std::vector<Node> targets;
255
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
256
            Node target = _graph.target(e);
257

	
258
            if (order_map[source] < order_map[target] && tree_map[e]) {
259
              targets.push_back(target);
260
            }
261
          }
262

	
263
          if (targets.size() == 0) {
264
            child_lists[source].first = INVALID;
265
          } else if (targets.size() == 1) {
266
            child_lists[source].first = targets[0];
267
            child_lists[targets[0]].prev = INVALID;
268
            child_lists[targets[0]].next = INVALID;
269
          } else {
270
            radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
271
            for (int i = 1; i < int(targets.size()); ++i) {
272
              child_lists[targets[i]].prev = targets[i - 1];
273
              child_lists[targets[i - 1]].next = targets[i];
274
            }
275
            child_lists[targets.back()].next = INVALID;
276
            child_lists[targets.front()].prev = INVALID;
277
            child_lists[source].first = targets.front();
278
          }
279
        }
280
      }
281

	
282
      void walkUp(const Node& node, Node root, int rorder,
283
                  const PredMap& pred_map, const LowMap& low_map,
284
                  const OrderMap& order_map, const OrderList& order_list,
285
                  NodeData& node_data, MergeRoots& merge_roots) {
286

	
287
        int na, nb;
288
        bool da, db;
289

	
290
        na = nb = order_map[node];
291
        da = true; db = false;
292

	
293
        while (true) {
294

	
295
          if (node_data[na].visited == rorder) break;
296
          if (node_data[nb].visited == rorder) break;
297

	
298
          node_data[na].visited = rorder;
299
          node_data[nb].visited = rorder;
300

	
301
          int rn = -1;
302

	
303
          if (na >= int(order_list.size())) {
304
            rn = na;
305
          } else if (nb >= int(order_list.size())) {
306
            rn = nb;
307
          }
308

	
309
          if (rn == -1) {
310
            int nn;
311

	
312
            nn = da ? node_data[na].prev : node_data[na].next;
313
            da = node_data[nn].prev != na;
314
            na = nn;
315

	
316
            nn = db ? node_data[nb].prev : node_data[nb].next;
317
            db = node_data[nn].prev != nb;
318
            nb = nn;
319

	
320
          } else {
321

	
322
            Node rep = order_list[rn - order_list.size()];
323
            Node parent = _graph.source(pred_map[rep]);
324

	
325
            if (low_map[rep] < rorder) {
326
              merge_roots[parent].push_back(rn);
327
            } else {
328
              merge_roots[parent].push_front(rn);
329
            }
330

	
331
            if (parent != root) {
332
              na = nb = order_map[parent];
333
              da = true; db = false;
334
            } else {
335
              break;
336
            }
337
          }
338
        }
339
      }
340

	
341
      void walkDown(int rn, int rorder, NodeData& node_data,
342
                    OrderList& order_list, ChildLists& child_lists,
343
                    AncestorMap& ancestor_map, LowMap& low_map,
344
                    EmbedArc& embed_arc, MergeRoots& merge_roots) {
345

	
346
        std::vector<std::pair<int, bool> > merge_stack;
347

	
348
        for (int di = 0; di < 2; ++di) {
349
          bool rd = di == 0;
350
          int pn = rn;
351
          int n = rd ? node_data[rn].next : node_data[rn].prev;
352

	
353
          while (n != rn) {
354

	
355
            Node node = order_list[n];
356

	
357
            if (embed_arc[node]) {
358

	
359
              // Merging components on the critical path
360
              while (!merge_stack.empty()) {
361

	
362
                // Component root
363
                int cn = merge_stack.back().first;
364
                bool cd = merge_stack.back().second;
365
                merge_stack.pop_back();
366

	
367
                // Parent of component
368
                int dn = merge_stack.back().first;
369
                bool dd = merge_stack.back().second;
370
                merge_stack.pop_back();
371

	
372
                Node parent = order_list[dn];
373

	
374
                // Erasing from merge_roots
375
                merge_roots[parent].pop_front();
376

	
377
                Node child = order_list[cn - order_list.size()];
378

	
379
                // Erasing from child_lists
380
                if (child_lists[child].prev != INVALID) {
381
                  child_lists[child_lists[child].prev].next =
382
                    child_lists[child].next;
383
                } else {
384
                  child_lists[parent].first = child_lists[child].next;
385
                }
386

	
387
                if (child_lists[child].next != INVALID) {
388
                  child_lists[child_lists[child].next].prev =
389
                    child_lists[child].prev;
390
                }
391

	
392
                // Merging external faces
393
                {
394
                  int en = cn;
395
                  cn = cd ? node_data[cn].prev : node_data[cn].next;
396
                  cd = node_data[cn].next == en;
397

	
398
                }
399

	
400
                if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
401
                if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
402

	
403
              }
404

	
405
              bool d = pn == node_data[n].prev;
406

	
407
              if (node_data[n].prev == node_data[n].next &&
408
                  node_data[n].inverted) {
409
                d = !d;
410
              }
411

	
412
              // Embedding arc into external face
413
              if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
414
              if (d) node_data[n].prev = rn; else node_data[n].next = rn;
415
              pn = rn;
416

	
417
              embed_arc[order_list[n]] = false;
418
            }
419

	
420
            if (!merge_roots[node].empty()) {
421

	
422
              bool d = pn == node_data[n].prev;
423

	
424
              merge_stack.push_back(std::make_pair(n, d));
425

	
426
              int rn = merge_roots[node].front();
427

	
428
              int xn = node_data[rn].next;
429
              Node xnode = order_list[xn];
430

	
431
              int yn = node_data[rn].prev;
432
              Node ynode = order_list[yn];
433

	
434
              bool rd;
435
              if (!external(xnode, rorder, child_lists, 
436
                            ancestor_map, low_map)) {
437
                rd = true;
438
              } else if (!external(ynode, rorder, child_lists,
439
                                   ancestor_map, low_map)) {
440
                rd = false;
441
              } else if (pertinent(xnode, embed_arc, merge_roots)) {
442
                rd = true;
443
              } else {
444
                rd = false;
445
              }
446

	
447
              merge_stack.push_back(std::make_pair(rn, rd));
448

	
449
              pn = rn;
450
              n = rd ? xn : yn;
451

	
452
            } else if (!external(node, rorder, child_lists,
453
                                 ancestor_map, low_map)) {
454
              int nn = (node_data[n].next != pn ?
455
                        node_data[n].next : node_data[n].prev);
456

	
457
              bool nd = n == node_data[nn].prev;
458

	
459
              if (nd) node_data[nn].prev = pn;
460
              else node_data[nn].next = pn;
461

	
462
              if (n == node_data[pn].prev) node_data[pn].prev = nn;
463
              else node_data[pn].next = nn;
464

	
465
              node_data[nn].inverted =
466
                (node_data[nn].prev == node_data[nn].next && nd != rd);
467

	
468
              n = nn;
469
            }
470
            else break;
471

	
472
          }
473

	
474
          if (!merge_stack.empty() || n == rn) {
475
            break;
476
          }
477
        }
478
      }
479

	
480
      void initFace(const Node& node, NodeData& node_data,
481
                    const OrderMap& order_map, const OrderList& order_list) {
482
        int n = order_map[node];
483
        int rn = n + order_list.size();
484

	
485
        node_data[n].next = node_data[n].prev = rn;
486
        node_data[rn].next = node_data[rn].prev = n;
487

	
488
        node_data[n].visited = order_list.size();
489
        node_data[rn].visited = order_list.size();
490

	
491
      }
492

	
493
      bool external(const Node& node, int rorder,
494
                    ChildLists& child_lists, AncestorMap& ancestor_map,
495
                    LowMap& low_map) {
496
        Node child = child_lists[node].first;
497

	
498
        if (child != INVALID) {
499
          if (low_map[child] < rorder) return true;
500
        }
501

	
502
        if (ancestor_map[node] < rorder) return true;
503

	
504
        return false;
505
      }
506

	
507
      bool pertinent(const Node& node, const EmbedArc& embed_arc,
508
                     const MergeRoots& merge_roots) {
509
        return !merge_roots[node].empty() || embed_arc[node];
510
      }
511

	
512
    };
513

	
514
  }
515

	
516
  /// \ingroup planar
517
  ///
518
  /// \brief Planarity checking of an undirected simple graph
519
  ///
520
  /// This function implements the Boyer-Myrvold algorithm for
521
  /// planarity checking of an undirected graph. It is a simplified
522
  /// version of the PlanarEmbedding algorithm class because neither
523
  /// the embedding nor the kuratowski subdivisons are not computed.
524
  template <typename GR>
525
  bool checkPlanarity(const GR& graph) {
526
    _planarity_bits::PlanarityChecking<GR> pc(graph);
527
    return pc.run();
528
  }
529

	
530
  /// \ingroup planar
531
  ///
532
  /// \brief Planar embedding of an undirected simple graph
533
  ///
534
  /// This class implements the Boyer-Myrvold algorithm for planar
535
  /// embedding of an undirected graph. The planar embedding is an
536
  /// ordering of the outgoing edges of the nodes, which is a possible
537
  /// configuration to draw the graph in the plane. If there is not
538
  /// such ordering then the graph contains a \f$ K_5 \f$ (full graph
539
  /// with 5 nodes) or a \f$ K_{3,3} \f$ (complete bipartite graph on
540
  /// 3 ANode and 3 BNode) subdivision.
541
  ///
542
  /// The current implementation calculates either an embedding or a
543
  /// Kuratowski subdivision. The running time of the algorithm is 
544
  /// \f$ O(n) \f$.
545
  template <typename Graph>
546
  class PlanarEmbedding {
547
  private:
548

	
549
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
550

	
551
    const Graph& _graph;
552
    typename Graph::template ArcMap<Arc> _embedding;
553

	
554
    typename Graph::template EdgeMap<bool> _kuratowski;
555

	
556
  private:
557

	
558
    typedef typename Graph::template NodeMap<Arc> PredMap;
559

	
560
    typedef typename Graph::template EdgeMap<bool> TreeMap;
561

	
562
    typedef typename Graph::template NodeMap<int> OrderMap;
563
    typedef std::vector<Node> OrderList;
564

	
565
    typedef typename Graph::template NodeMap<int> LowMap;
566
    typedef typename Graph::template NodeMap<int> AncestorMap;
567

	
568
    typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
569
    typedef std::vector<NodeDataNode> NodeData;
570

	
571
    typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
572
    typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
573

	
574
    typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
575

	
576
    typedef typename Graph::template NodeMap<Arc> EmbedArc;
577

	
578
    typedef _planarity_bits::ArcListNode<Graph> ArcListNode;
579
    typedef typename Graph::template ArcMap<ArcListNode> ArcLists;
580

	
581
    typedef typename Graph::template NodeMap<bool> FlipMap;
582

	
583
    typedef typename Graph::template NodeMap<int> TypeMap;
584

	
585
    enum IsolatorNodeType {
586
      HIGHX = 6, LOWX = 7,
587
      HIGHY = 8, LOWY = 9,
588
      ROOT = 10, PERTINENT = 11,
589
      INTERNAL = 12
590
    };
591

	
592
  public:
593

	
594
    /// \brief The map for store of embedding
595
    typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
596

	
597
    /// \brief Constructor
598
    ///
599
    /// \note The graph should be simple, i.e. parallel and loop arc
600
    /// free.
601
    PlanarEmbedding(const Graph& graph)
602
      : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
603

	
604
    /// \brief Runs the algorithm.
605
    ///
606
    /// Runs the algorithm.
607
    /// \param kuratowski If the parameter is false, then the
608
    /// algorithm does not compute a Kuratowski subdivision.
609
    ///\return %True when the graph is planar.
610
    bool run(bool kuratowski = true) {
611
      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
612

	
613
      PredMap pred_map(_graph, INVALID);
614
      TreeMap tree_map(_graph, false);
615

	
616
      OrderMap order_map(_graph, -1);
617
      OrderList order_list;
618

	
619
      AncestorMap ancestor_map(_graph, -1);
620
      LowMap low_map(_graph, -1);
621

	
622
      Visitor visitor(_graph, pred_map, tree_map,
623
                      order_map, order_list, ancestor_map, low_map);
624
      DfsVisit<Graph, Visitor> visit(_graph, visitor);
625
      visit.run();
626

	
627
      ChildLists child_lists(_graph);
628
      createChildLists(tree_map, order_map, low_map, child_lists);
629

	
630
      NodeData node_data(2 * order_list.size());
631

	
632
      EmbedArc embed_arc(_graph, INVALID);
633

	
634
      MergeRoots merge_roots(_graph);
635

	
636
      ArcLists arc_lists(_graph);
637

	
638
      FlipMap flip_map(_graph, false);
639

	
640
      for (int i = order_list.size() - 1; i >= 0; --i) {
641

	
642
        Node node = order_list[i];
643

	
644
        node_data[i].first = INVALID;
645

	
646
        Node source = node;
647
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
648
          Node target = _graph.target(e);
649

	
650
          if (order_map[source] < order_map[target] && tree_map[e]) {
651
            initFace(target, arc_lists, node_data,
652
                     pred_map, order_map, order_list);
653
          }
654
        }
655

	
656
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
657
          Node target = _graph.target(e);
658

	
659
          if (order_map[source] < order_map[target] && !tree_map[e]) {
660
            embed_arc[target] = e;
661
            walkUp(target, source, i, pred_map, low_map,
662
                   order_map, order_list, node_data, merge_roots);
663
          }
664
        }
665

	
666
        for (typename MergeRoots::Value::iterator it =
667
               merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
668
          int rn = *it;
669
          walkDown(rn, i, node_data, arc_lists, flip_map, order_list,
670
                   child_lists, ancestor_map, low_map, embed_arc, merge_roots);
671
        }
672
        merge_roots[node].clear();
673

	
674
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
675
          Node target = _graph.target(e);
676

	
677
          if (order_map[source] < order_map[target] && !tree_map[e]) {
678
            if (embed_arc[target] != INVALID) {
679
              if (kuratowski) {
680
                isolateKuratowski(e, node_data, arc_lists, flip_map,
681
                                  order_map, order_list, pred_map, child_lists,
682
                                  ancestor_map, low_map,
683
                                  embed_arc, merge_roots);
684
              }
685
              return false;
686
            }
687
          }
688
        }
689
      }
690

	
691
      for (int i = 0; i < int(order_list.size()); ++i) {
692

	
693
        mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
694
                            child_lists, arc_lists);
695
        storeEmbedding(order_list[i], node_data, order_map, pred_map,
696
                       arc_lists, flip_map);
697
      }
698

	
699
      return true;
700
    }
701

	
702
    /// \brief Gives back the successor of an arc
703
    ///
704
    /// Gives back the successor of an arc. This function makes
705
    /// possible to query the cyclic order of the outgoing arcs from
706
    /// a node.
707
    Arc next(const Arc& arc) const {
708
      return _embedding[arc];
709
    }
710

	
711
    /// \brief Gives back the calculated embedding map
712
    ///
713
    /// The returned map contains the successor of each arc in the
714
    /// graph.
715
    const EmbeddingMap& embeddingMap() const {
716
      return _embedding;
717
    }
718

	
719
    /// \brief Gives back true if the undirected arc is in the
720
    /// kuratowski subdivision
721
    ///
722
    /// Gives back true if the undirected arc is in the kuratowski
723
    /// subdivision
724
    /// \note The \c run() had to be called with true value.
725
    bool kuratowski(const Edge& edge) {
726
      return _kuratowski[edge];
727
    }
728

	
729
  private:
730

	
731
    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
732
                          const LowMap& low_map, ChildLists& child_lists) {
733

	
734
      for (NodeIt n(_graph); n != INVALID; ++n) {
735
        Node source = n;
736

	
737
        std::vector<Node> targets;
738
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
739
          Node target = _graph.target(e);
740

	
741
          if (order_map[source] < order_map[target] && tree_map[e]) {
742
            targets.push_back(target);
743
          }
744
        }
745

	
746
        if (targets.size() == 0) {
747
          child_lists[source].first = INVALID;
748
        } else if (targets.size() == 1) {
749
          child_lists[source].first = targets[0];
750
          child_lists[targets[0]].prev = INVALID;
751
          child_lists[targets[0]].next = INVALID;
752
        } else {
753
          radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
754
          for (int i = 1; i < int(targets.size()); ++i) {
755
            child_lists[targets[i]].prev = targets[i - 1];
756
            child_lists[targets[i - 1]].next = targets[i];
757
          }
758
          child_lists[targets.back()].next = INVALID;
759
          child_lists[targets.front()].prev = INVALID;
760
          child_lists[source].first = targets.front();
761
        }
762
      }
763
    }
764

	
765
    void walkUp(const Node& node, Node root, int rorder,
766
                const PredMap& pred_map, const LowMap& low_map,
767
                const OrderMap& order_map, const OrderList& order_list,
768
                NodeData& node_data, MergeRoots& merge_roots) {
769

	
770
      int na, nb;
771
      bool da, db;
772

	
773
      na = nb = order_map[node];
774
      da = true; db = false;
775

	
776
      while (true) {
777

	
778
        if (node_data[na].visited == rorder) break;
779
        if (node_data[nb].visited == rorder) break;
780

	
781
        node_data[na].visited = rorder;
782
        node_data[nb].visited = rorder;
783

	
784
        int rn = -1;
785

	
786
        if (na >= int(order_list.size())) {
787
          rn = na;
788
        } else if (nb >= int(order_list.size())) {
789
          rn = nb;
790
        }
791

	
792
        if (rn == -1) {
793
          int nn;
794

	
795
          nn = da ? node_data[na].prev : node_data[na].next;
796
          da = node_data[nn].prev != na;
797
          na = nn;
798

	
799
          nn = db ? node_data[nb].prev : node_data[nb].next;
800
          db = node_data[nn].prev != nb;
801
          nb = nn;
802

	
803
        } else {
804

	
805
          Node rep = order_list[rn - order_list.size()];
806
          Node parent = _graph.source(pred_map[rep]);
807

	
808
          if (low_map[rep] < rorder) {
809
            merge_roots[parent].push_back(rn);
810
          } else {
811
            merge_roots[parent].push_front(rn);
812
          }
813

	
814
          if (parent != root) {
815
            na = nb = order_map[parent];
816
            da = true; db = false;
817
          } else {
818
            break;
819
          }
820
        }
821
      }
822
    }
823

	
824
    void walkDown(int rn, int rorder, NodeData& node_data,
825
                  ArcLists& arc_lists, FlipMap& flip_map,
826
                  OrderList& order_list, ChildLists& child_lists,
827
                  AncestorMap& ancestor_map, LowMap& low_map,
828
                  EmbedArc& embed_arc, MergeRoots& merge_roots) {
829

	
830
      std::vector<std::pair<int, bool> > merge_stack;
831

	
832
      for (int di = 0; di < 2; ++di) {
833
        bool rd = di == 0;
834
        int pn = rn;
835
        int n = rd ? node_data[rn].next : node_data[rn].prev;
836

	
837
        while (n != rn) {
838

	
839
          Node node = order_list[n];
840

	
841
          if (embed_arc[node] != INVALID) {
842

	
843
            // Merging components on the critical path
844
            while (!merge_stack.empty()) {
845

	
846
              // Component root
847
              int cn = merge_stack.back().first;
848
              bool cd = merge_stack.back().second;
849
              merge_stack.pop_back();
850

	
851
              // Parent of component
852
              int dn = merge_stack.back().first;
853
              bool dd = merge_stack.back().second;
854
              merge_stack.pop_back();
855

	
856
              Node parent = order_list[dn];
857

	
858
              // Erasing from merge_roots
859
              merge_roots[parent].pop_front();
860

	
861
              Node child = order_list[cn - order_list.size()];
862

	
863
              // Erasing from child_lists
864
              if (child_lists[child].prev != INVALID) {
865
                child_lists[child_lists[child].prev].next =
866
                  child_lists[child].next;
867
              } else {
868
                child_lists[parent].first = child_lists[child].next;
869
              }
870

	
871
              if (child_lists[child].next != INVALID) {
872
                child_lists[child_lists[child].next].prev =
873
                  child_lists[child].prev;
874
              }
875

	
876
              // Merging arcs + flipping
877
              Arc de = node_data[dn].first;
878
              Arc ce = node_data[cn].first;
879

	
880
              flip_map[order_list[cn - order_list.size()]] = cd != dd;
881
              if (cd != dd) {
882
                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
883
                ce = arc_lists[ce].prev;
884
                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
885
              }
886

	
887
              {
888
                Arc dne = arc_lists[de].next;
889
                Arc cne = arc_lists[ce].next;
890

	
891
                arc_lists[de].next = cne;
892
                arc_lists[ce].next = dne;
893

	
894
                arc_lists[dne].prev = ce;
895
                arc_lists[cne].prev = de;
896
              }
897

	
898
              if (dd) {
899
                node_data[dn].first = ce;
900
              }
901

	
902
              // Merging external faces
903
              {
904
                int en = cn;
905
                cn = cd ? node_data[cn].prev : node_data[cn].next;
906
                cd = node_data[cn].next == en;
907

	
908
                 if (node_data[cn].prev == node_data[cn].next &&
909
                    node_data[cn].inverted) {
910
                   cd = !cd;
911
                 }
912
              }
913

	
914
              if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
915
              if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
916

	
917
            }
918

	
919
            bool d = pn == node_data[n].prev;
920

	
921
            if (node_data[n].prev == node_data[n].next &&
922
                node_data[n].inverted) {
923
              d = !d;
924
            }
925

	
926
            // Add new arc
927
            {
928
              Arc arc = embed_arc[node];
929
              Arc re = node_data[rn].first;
930

	
931
              arc_lists[arc_lists[re].next].prev = arc;
932
              arc_lists[arc].next = arc_lists[re].next;
933
              arc_lists[arc].prev = re;
934
              arc_lists[re].next = arc;
935

	
936
              if (!rd) {
937
                node_data[rn].first = arc;
938
              }
939

	
940
              Arc rev = _graph.oppositeArc(arc);
941
              Arc e = node_data[n].first;
942

	
943
              arc_lists[arc_lists[e].next].prev = rev;
944
              arc_lists[rev].next = arc_lists[e].next;
945
              arc_lists[rev].prev = e;
946
              arc_lists[e].next = rev;
947

	
948
              if (d) {
949
                node_data[n].first = rev;
950
              }
951

	
952
            }
953

	
954
            // Embedding arc into external face
955
            if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
956
            if (d) node_data[n].prev = rn; else node_data[n].next = rn;
957
            pn = rn;
958

	
959
            embed_arc[order_list[n]] = INVALID;
960
          }
961

	
962
          if (!merge_roots[node].empty()) {
963

	
964
            bool d = pn == node_data[n].prev;
965
            if (node_data[n].prev == node_data[n].next &&
966
                node_data[n].inverted) {
967
              d = !d;
968
            }
969

	
970
            merge_stack.push_back(std::make_pair(n, d));
971

	
972
            int rn = merge_roots[node].front();
973

	
974
            int xn = node_data[rn].next;
975
            Node xnode = order_list[xn];
976

	
977
            int yn = node_data[rn].prev;
978
            Node ynode = order_list[yn];
979

	
980
            bool rd;
981
            if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
982
              rd = true;
983
            } else if (!external(ynode, rorder, child_lists,
984
                                 ancestor_map, low_map)) {
985
              rd = false;
986
            } else if (pertinent(xnode, embed_arc, merge_roots)) {
987
              rd = true;
988
            } else {
989
              rd = false;
990
            }
991

	
992
            merge_stack.push_back(std::make_pair(rn, rd));
993

	
994
            pn = rn;
995
            n = rd ? xn : yn;
996

	
997
          } else if (!external(node, rorder, child_lists,
998
                               ancestor_map, low_map)) {
999
            int nn = (node_data[n].next != pn ?
1000
                      node_data[n].next : node_data[n].prev);
1001

	
1002
            bool nd = n == node_data[nn].prev;
1003

	
1004
            if (nd) node_data[nn].prev = pn;
1005
            else node_data[nn].next = pn;
1006

	
1007
            if (n == node_data[pn].prev) node_data[pn].prev = nn;
1008
            else node_data[pn].next = nn;
1009

	
1010
            node_data[nn].inverted =
1011
              (node_data[nn].prev == node_data[nn].next && nd != rd);
1012

	
1013
            n = nn;
1014
          }
1015
          else break;
1016

	
1017
        }
1018

	
1019
        if (!merge_stack.empty() || n == rn) {
1020
          break;
1021
        }
1022
      }
1023
    }
1024

	
1025
    void initFace(const Node& node, ArcLists& arc_lists,
1026
                  NodeData& node_data, const PredMap& pred_map,
1027
                  const OrderMap& order_map, const OrderList& order_list) {
1028
      int n = order_map[node];
1029
      int rn = n + order_list.size();
1030

	
1031
      node_data[n].next = node_data[n].prev = rn;
1032
      node_data[rn].next = node_data[rn].prev = n;
1033

	
1034
      node_data[n].visited = order_list.size();
1035
      node_data[rn].visited = order_list.size();
1036

	
1037
      node_data[n].inverted = false;
1038
      node_data[rn].inverted = false;
1039

	
1040
      Arc arc = pred_map[node];
1041
      Arc rev = _graph.oppositeArc(arc);
1042

	
1043
      node_data[rn].first = arc;
1044
      node_data[n].first = rev;
1045

	
1046
      arc_lists[arc].prev = arc;
1047
      arc_lists[arc].next = arc;
1048

	
1049
      arc_lists[rev].prev = rev;
1050
      arc_lists[rev].next = rev;
1051

	
1052
    }
1053

	
1054
    void mergeRemainingFaces(const Node& node, NodeData& node_data,
1055
                             OrderList& order_list, OrderMap& order_map,
1056
                             ChildLists& child_lists, ArcLists& arc_lists) {
1057
      while (child_lists[node].first != INVALID) {
1058
        int dd = order_map[node];
1059
        Node child = child_lists[node].first;
1060
        int cd = order_map[child] + order_list.size();
1061
        child_lists[node].first = child_lists[child].next;
1062

	
1063
        Arc de = node_data[dd].first;
1064
        Arc ce = node_data[cd].first;
1065

	
1066
        if (de != INVALID) {
1067
          Arc dne = arc_lists[de].next;
1068
          Arc cne = arc_lists[ce].next;
1069

	
1070
          arc_lists[de].next = cne;
1071
          arc_lists[ce].next = dne;
1072

	
1073
          arc_lists[dne].prev = ce;
1074
          arc_lists[cne].prev = de;
1075
        }
1076

	
1077
        node_data[dd].first = ce;
1078

	
1079
      }
1080
    }
1081

	
1082
    void storeEmbedding(const Node& node, NodeData& node_data,
1083
                        OrderMap& order_map, PredMap& pred_map,
1084
                        ArcLists& arc_lists, FlipMap& flip_map) {
1085

	
1086
      if (node_data[order_map[node]].first == INVALID) return;
1087

	
1088
      if (pred_map[node] != INVALID) {
1089
        Node source = _graph.source(pred_map[node]);
1090
        flip_map[node] = flip_map[node] != flip_map[source];
1091
      }
1092

	
1093
      Arc first = node_data[order_map[node]].first;
1094
      Arc prev = first;
1095

	
1096
      Arc arc = flip_map[node] ?
1097
        arc_lists[prev].prev : arc_lists[prev].next;
1098

	
1099
      _embedding[prev] = arc;
1100

	
1101
      while (arc != first) {
1102
        Arc next = arc_lists[arc].prev == prev ?
1103
          arc_lists[arc].next : arc_lists[arc].prev;
1104
        prev = arc; arc = next;
1105
        _embedding[prev] = arc;
1106
      }
1107
    }
1108

	
1109

	
1110
    bool external(const Node& node, int rorder,
1111
                  ChildLists& child_lists, AncestorMap& ancestor_map,
1112
                  LowMap& low_map) {
1113
      Node child = child_lists[node].first;
1114

	
1115
      if (child != INVALID) {
1116
        if (low_map[child] < rorder) return true;
1117
      }
1118

	
1119
      if (ancestor_map[node] < rorder) return true;
1120

	
1121
      return false;
1122
    }
1123

	
1124
    bool pertinent(const Node& node, const EmbedArc& embed_arc,
1125
                   const MergeRoots& merge_roots) {
1126
      return !merge_roots[node].empty() || embed_arc[node] != INVALID;
1127
    }
1128

	
1129
    int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
1130
                 AncestorMap& ancestor_map, LowMap& low_map) {
1131
      int low_point;
1132

	
1133
      Node child = child_lists[node].first;
1134

	
1135
      if (child != INVALID) {
1136
        low_point = low_map[child];
1137
      } else {
1138
        low_point = order_map[node];
1139
      }
1140

	
1141
      if (low_point > ancestor_map[node]) {
1142
        low_point = ancestor_map[node];
1143
      }
1144

	
1145
      return low_point;
1146
    }
1147

	
1148
    int findComponentRoot(Node root, Node node, ChildLists& child_lists,
1149
                          OrderMap& order_map, OrderList& order_list) {
1150

	
1151
      int order = order_map[root];
1152
      int norder = order_map[node];
1153

	
1154
      Node child = child_lists[root].first;
1155
      while (child != INVALID) {
1156
        int corder = order_map[child];
1157
        if (corder > order && corder < norder) {
1158
          order = corder;
1159
        }
1160
        child = child_lists[child].next;
1161
      }
1162
      return order + order_list.size();
1163
    }
1164

	
1165
    Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
1166
                       EmbedArc& embed_arc, MergeRoots& merge_roots) {
1167
      Node wnode =_graph.target(node_data[order_map[node]].first);
1168
      while (!pertinent(wnode, embed_arc, merge_roots)) {
1169
        wnode = _graph.target(node_data[order_map[wnode]].first);
1170
      }
1171
      return wnode;
1172
    }
1173

	
1174

	
1175
    Node findExternal(Node node, int rorder, OrderMap& order_map,
1176
                      ChildLists& child_lists, AncestorMap& ancestor_map,
1177
                      LowMap& low_map, NodeData& node_data) {
1178
      Node wnode =_graph.target(node_data[order_map[node]].first);
1179
      while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1180
        wnode = _graph.target(node_data[order_map[wnode]].first);
1181
      }
1182
      return wnode;
1183
    }
1184

	
1185
    void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
1186
                        OrderList& order_list, OrderMap& order_map,
1187
                        NodeData& node_data, ArcLists& arc_lists,
1188
                        EmbedArc& embed_arc, MergeRoots& merge_roots,
1189
                        ChildLists& child_lists, AncestorMap& ancestor_map,
1190
                        LowMap& low_map) {
1191

	
1192
      Node cnode = node;
1193
      Node pred = INVALID;
1194

	
1195
      while (true) {
1196

	
1197
        bool pert = pertinent(cnode, embed_arc, merge_roots);
1198
        bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
1199

	
1200
        if (pert && ext) {
1201
          if (!merge_roots[cnode].empty()) {
1202
            int cn = merge_roots[cnode].back();
1203

	
1204
            if (low_map[order_list[cn - order_list.size()]] < rorder) {
1205
              Arc arc = node_data[cn].first;
1206
              _kuratowski.set(arc, true);
1207

	
1208
              pred = cnode;
1209
              cnode = _graph.target(arc);
1210

	
1211
              continue;
1212
            }
1213
          }
1214
          wnode = znode = cnode;
1215
          return;
1216

	
1217
        } else if (pert) {
1218
          wnode = cnode;
1219

	
1220
          while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
1221
            Arc arc = node_data[order_map[cnode]].first;
1222

	
1223
            if (_graph.target(arc) == pred) {
1224
              arc = arc_lists[arc].next;
1225
            }
1226
            _kuratowski.set(arc, true);
1227

	
1228
            Node next = _graph.target(arc);
1229
            pred = cnode; cnode = next;
1230
          }
1231

	
1232
          znode = cnode;
1233
          return;
1234

	
1235
        } else if (ext) {
1236
          znode = cnode;
1237

	
1238
          while (!pertinent(cnode, embed_arc, merge_roots)) {
1239
            Arc arc = node_data[order_map[cnode]].first;
1240

	
1241
            if (_graph.target(arc) == pred) {
1242
              arc = arc_lists[arc].next;
1243
            }
1244
            _kuratowski.set(arc, true);
1245

	
1246
            Node next = _graph.target(arc);
1247
            pred = cnode; cnode = next;
1248
          }
1249

	
1250
          wnode = cnode;
1251
          return;
1252

	
1253
        } else {
1254
          Arc arc = node_data[order_map[cnode]].first;
1255

	
1256
          if (_graph.target(arc) == pred) {
1257
            arc = arc_lists[arc].next;
1258
          }
1259
          _kuratowski.set(arc, true);
1260

	
1261
          Node next = _graph.target(arc);
1262
          pred = cnode; cnode = next;
1263
        }
1264

	
1265
      }
1266

	
1267
    }
1268

	
1269
    void orientComponent(Node root, int rn, OrderMap& order_map,
1270
                         PredMap& pred_map, NodeData& node_data,
1271
                         ArcLists& arc_lists, FlipMap& flip_map,
1272
                         TypeMap& type_map) {
1273
      node_data[order_map[root]].first = node_data[rn].first;
1274
      type_map[root] = 1;
1275

	
1276
      std::vector<Node> st, qu;
1277

	
1278
      st.push_back(root);
1279
      while (!st.empty()) {
1280
        Node node = st.back();
1281
        st.pop_back();
1282
        qu.push_back(node);
1283

	
1284
        Arc arc = node_data[order_map[node]].first;
1285

	
1286
        if (type_map[_graph.target(arc)] == 0) {
1287
          st.push_back(_graph.target(arc));
1288
          type_map[_graph.target(arc)] = 1;
1289
        }
1290

	
1291
        Arc last = arc, pred = arc;
1292
        arc = arc_lists[arc].next;
1293
        while (arc != last) {
1294

	
1295
          if (type_map[_graph.target(arc)] == 0) {
1296
            st.push_back(_graph.target(arc));
1297
            type_map[_graph.target(arc)] = 1;
1298
          }
1299

	
1300
          Arc next = arc_lists[arc].next != pred ?
1301
            arc_lists[arc].next : arc_lists[arc].prev;
1302
          pred = arc; arc = next;
1303
        }
1304

	
1305
      }
1306

	
1307
      type_map[root] = 2;
1308
      flip_map[root] = false;
1309

	
1310
      for (int i = 1; i < int(qu.size()); ++i) {
1311

	
1312
        Node node = qu[i];
1313

	
1314
        while (type_map[node] != 2) {
1315
          st.push_back(node);
1316
          type_map[node] = 2;
1317
          node = _graph.source(pred_map[node]);
1318
        }
1319

	
1320
        bool flip = flip_map[node];
1321

	
1322
        while (!st.empty()) {
1323
          node = st.back();
1324
          st.pop_back();
1325

	
1326
          flip_map[node] = flip != flip_map[node];
1327
          flip = flip_map[node];
1328

	
1329
          if (flip) {
1330
            Arc arc = node_data[order_map[node]].first;
1331
            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
1332
            arc = arc_lists[arc].prev;
1333
            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
1334
            node_data[order_map[node]].first = arc;
1335
          }
1336
        }
1337
      }
1338

	
1339
      for (int i = 0; i < int(qu.size()); ++i) {
1340

	
1341
        Arc arc = node_data[order_map[qu[i]]].first;
1342
        Arc last = arc, pred = arc;
1343

	
1344
        arc = arc_lists[arc].next;
1345
        while (arc != last) {
1346

	
1347
          if (arc_lists[arc].next == pred) {
1348
            std::swap(arc_lists[arc].next, arc_lists[arc].prev);
1349
          }
1350
          pred = arc; arc = arc_lists[arc].next;
1351
        }
1352

	
1353
      }
1354
    }
1355

	
1356
    void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
1357
                      OrderMap& order_map, NodeData& node_data,
1358
                      TypeMap& type_map) {
1359
      Node node = _graph.target(node_data[order_map[root]].first);
1360

	
1361
      while (node != ynode) {
1362
        type_map[node] = HIGHY;
1363
        node = _graph.target(node_data[order_map[node]].first);
1364
      }
1365

	
1366
      while (node != wnode) {
1367
        type_map[node] = LOWY;
1368
        node = _graph.target(node_data[order_map[node]].first);
1369
      }
1370

	
1371
      node = _graph.target(node_data[order_map[wnode]].first);
1372

	
1373
      while (node != xnode) {
1374
        type_map[node] = LOWX;
1375
        node = _graph.target(node_data[order_map[node]].first);
1376
      }
1377
      type_map[node] = LOWX;
1378

	
1379
      node = _graph.target(node_data[order_map[xnode]].first);
1380
      while (node != root) {
1381
        type_map[node] = HIGHX;
1382
        node = _graph.target(node_data[order_map[node]].first);
1383
      }
1384

	
1385
      type_map[wnode] = PERTINENT;
1386
      type_map[root] = ROOT;
1387
    }
1388

	
1389
    void findInternalPath(std::vector<Arc>& ipath,
1390
                          Node wnode, Node root, TypeMap& type_map,
1391
                          OrderMap& order_map, NodeData& node_data,
1392
                          ArcLists& arc_lists) {
1393
      std::vector<Arc> st;
1394

	
1395
      Node node = wnode;
1396

	
1397
      while (node != root) {
1398
        Arc arc = arc_lists[node_data[order_map[node]].first].next;
1399
        st.push_back(arc);
1400
        node = _graph.target(arc);
1401
      }
1402

	
1403
      while (true) {
1404
        Arc arc = st.back();
1405
        if (type_map[_graph.target(arc)] == LOWX ||
1406
            type_map[_graph.target(arc)] == HIGHX) {
1407
          break;
1408
        }
1409
        if (type_map[_graph.target(arc)] == 2) {
1410
          type_map[_graph.target(arc)] = 3;
1411

	
1412
          arc = arc_lists[_graph.oppositeArc(arc)].next;
1413
          st.push_back(arc);
1414
        } else {
1415
          st.pop_back();
1416
          arc = arc_lists[arc].next;
1417

	
1418
          while (_graph.oppositeArc(arc) == st.back()) {
1419
            arc = st.back();
1420
            st.pop_back();
1421
            arc = arc_lists[arc].next;
1422
          }
1423
          st.push_back(arc);
1424
        }
1425
      }
1426

	
1427
      for (int i = 0; i < int(st.size()); ++i) {
1428
        if (type_map[_graph.target(st[i])] != LOWY &&
1429
            type_map[_graph.target(st[i])] != HIGHY) {
1430
          for (; i < int(st.size()); ++i) {
1431
            ipath.push_back(st[i]);
1432
          }
1433
        }
1434
      }
1435
    }
1436

	
1437
    void setInternalFlags(std::vector<Arc>& ipath, TypeMap& type_map) {
1438
      for (int i = 1; i < int(ipath.size()); ++i) {
1439
        type_map[_graph.source(ipath[i])] = INTERNAL;
1440
      }
1441
    }
1442

	
1443
    void findPilePath(std::vector<Arc>& ppath,
1444
                      Node root, TypeMap& type_map, OrderMap& order_map,
1445
                      NodeData& node_data, ArcLists& arc_lists) {
1446
      std::vector<Arc> st;
1447

	
1448
      st.push_back(_graph.oppositeArc(node_data[order_map[root]].first));
1449
      st.push_back(node_data[order_map[root]].first);
1450

	
1451
      while (st.size() > 1) {
1452
        Arc arc = st.back();
1453
        if (type_map[_graph.target(arc)] == INTERNAL) {
1454
          break;
1455
        }
1456
        if (type_map[_graph.target(arc)] == 3) {
1457
          type_map[_graph.target(arc)] = 4;
1458

	
1459
          arc = arc_lists[_graph.oppositeArc(arc)].next;
1460
          st.push_back(arc);
1461
        } else {
1462
          st.pop_back();
1463
          arc = arc_lists[arc].next;
1464

	
1465
          while (!st.empty() && _graph.oppositeArc(arc) == st.back()) {
1466
            arc = st.back();
1467
            st.pop_back();
1468
            arc = arc_lists[arc].next;
1469
          }
1470
          st.push_back(arc);
1471
        }
1472
      }
1473

	
1474
      for (int i = 1; i < int(st.size()); ++i) {
1475
        ppath.push_back(st[i]);
1476
      }
1477
    }
1478

	
1479

	
1480
    int markExternalPath(Node node, OrderMap& order_map,
1481
                         ChildLists& child_lists, PredMap& pred_map,
1482
                         AncestorMap& ancestor_map, LowMap& low_map) {
1483
      int lp = lowPoint(node, order_map, child_lists,
1484
                        ancestor_map, low_map);
1485

	
1486
      if (ancestor_map[node] != lp) {
1487
        node = child_lists[node].first;
1488
        _kuratowski[pred_map[node]] = true;
1489

	
1490
        while (ancestor_map[node] != lp) {
1491
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
1492
            Node tnode = _graph.target(e);
1493
            if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
1494
              node = tnode;
1495
              _kuratowski[e] = true;
1496
              break;
1497
            }
1498
          }
1499
        }
1500
      }
1501

	
1502
      for (OutArcIt e(_graph, node); e != INVALID; ++e) {
1503
        if (order_map[_graph.target(e)] == lp) {
1504
          _kuratowski[e] = true;
1505
          break;
1506
        }
1507
      }
1508

	
1509
      return lp;
1510
    }
1511

	
1512
    void markPertinentPath(Node node, OrderMap& order_map,
1513
                           NodeData& node_data, ArcLists& arc_lists,
1514
                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
1515
      while (embed_arc[node] == INVALID) {
1516
        int n = merge_roots[node].front();
1517
        Arc arc = node_data[n].first;
1518

	
1519
        _kuratowski.set(arc, true);
1520

	
1521
        Node pred = node;
1522
        node = _graph.target(arc);
1523
        while (!pertinent(node, embed_arc, merge_roots)) {
1524
          arc = node_data[order_map[node]].first;
1525
          if (_graph.target(arc) == pred) {
1526
            arc = arc_lists[arc].next;
1527
          }
1528
          _kuratowski.set(arc, true);
1529
          pred = node;
1530
          node = _graph.target(arc);
1531
        }
1532
      }
1533
      _kuratowski.set(embed_arc[node], true);
1534
    }
1535

	
1536
    void markPredPath(Node node, Node snode, PredMap& pred_map) {
1537
      while (node != snode) {
1538
        _kuratowski.set(pred_map[node], true);
1539
        node = _graph.source(pred_map[node]);
1540
      }
1541
    }
1542

	
1543
    void markFacePath(Node ynode, Node xnode,
1544
                      OrderMap& order_map, NodeData& node_data) {
1545
      Arc arc = node_data[order_map[ynode]].first;
1546
      Node node = _graph.target(arc);
1547
      _kuratowski.set(arc, true);
1548

	
1549
      while (node != xnode) {
1550
        arc = node_data[order_map[node]].first;
1551
        _kuratowski.set(arc, true);
1552
        node = _graph.target(arc);
1553
      }
1554
    }
1555

	
1556
    void markInternalPath(std::vector<Arc>& path) {
1557
      for (int i = 0; i < int(path.size()); ++i) {
1558
        _kuratowski.set(path[i], true);
1559
      }
1560
    }
1561

	
1562
    void markPilePath(std::vector<Arc>& path) {
1563
      for (int i = 0; i < int(path.size()); ++i) {
1564
        _kuratowski.set(path[i], true);
1565
      }
1566
    }
1567

	
1568
    void isolateKuratowski(Arc arc, NodeData& node_data,
1569
                           ArcLists& arc_lists, FlipMap& flip_map,
1570
                           OrderMap& order_map, OrderList& order_list,
1571
                           PredMap& pred_map, ChildLists& child_lists,
1572
                           AncestorMap& ancestor_map, LowMap& low_map,
1573
                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
1574

	
1575
      Node root = _graph.source(arc);
1576
      Node enode = _graph.target(arc);
1577

	
1578
      int rorder = order_map[root];
1579

	
1580
      TypeMap type_map(_graph, 0);
1581

	
1582
      int rn = findComponentRoot(root, enode, child_lists,
1583
                                 order_map, order_list);
1584

	
1585
      Node xnode = order_list[node_data[rn].next];
1586
      Node ynode = order_list[node_data[rn].prev];
1587

	
1588
      // Minor-A
1589
      {
1590
        while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
1591

	
1592
          if (!merge_roots[xnode].empty()) {
1593
            root = xnode;
1594
            rn = merge_roots[xnode].front();
1595
          } else {
1596
            root = ynode;
1597
            rn = merge_roots[ynode].front();
1598
          }
1599

	
1600
          xnode = order_list[node_data[rn].next];
1601
          ynode = order_list[node_data[rn].prev];
1602
        }
1603

	
1604
        if (root != _graph.source(arc)) {
1605
          orientComponent(root, rn, order_map, pred_map,
1606
                          node_data, arc_lists, flip_map, type_map);
1607
          markFacePath(root, root, order_map, node_data);
1608
          int xlp = markExternalPath(xnode, order_map, child_lists,
1609
                                     pred_map, ancestor_map, low_map);
1610
          int ylp = markExternalPath(ynode, order_map, child_lists,
1611
                                     pred_map, ancestor_map, low_map);
1612
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1613
          Node lwnode = findPertinent(ynode, order_map, node_data,
1614
                                      embed_arc, merge_roots);
1615

	
1616
          markPertinentPath(lwnode, order_map, node_data, arc_lists,
1617
                            embed_arc, merge_roots);
1618

	
1619
          return;
1620
        }
1621
      }
1622

	
1623
      orientComponent(root, rn, order_map, pred_map,
1624
                      node_data, arc_lists, flip_map, type_map);
1625

	
1626
      Node wnode = findPertinent(ynode, order_map, node_data,
1627
                                 embed_arc, merge_roots);
1628
      setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
1629

	
1630

	
1631
      //Minor-B
1632
      if (!merge_roots[wnode].empty()) {
1633
        int cn = merge_roots[wnode].back();
1634
        Node rep = order_list[cn - order_list.size()];
1635
        if (low_map[rep] < rorder) {
1636
          markFacePath(root, root, order_map, node_data);
1637
          int xlp = markExternalPath(xnode, order_map, child_lists,
1638
                                     pred_map, ancestor_map, low_map);
1639
          int ylp = markExternalPath(ynode, order_map, child_lists,
1640
                                     pred_map, ancestor_map, low_map);
1641

	
1642
          Node lwnode, lznode;
1643
          markCommonPath(wnode, rorder, lwnode, lznode, order_list,
1644
                         order_map, node_data, arc_lists, embed_arc,
1645
                         merge_roots, child_lists, ancestor_map, low_map);
1646

	
1647
          markPertinentPath(lwnode, order_map, node_data, arc_lists,
1648
                            embed_arc, merge_roots);
1649
          int zlp = markExternalPath(lznode, order_map, child_lists,
1650
                                     pred_map, ancestor_map, low_map);
1651

	
1652
          int minlp = xlp < ylp ? xlp : ylp;
1653
          if (zlp < minlp) minlp = zlp;
1654

	
1655
          int maxlp = xlp > ylp ? xlp : ylp;
1656
          if (zlp > maxlp) maxlp = zlp;
1657

	
1658
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1659

	
1660
          return;
1661
        }
1662
      }
1663

	
1664
      Node pxnode, pynode;
1665
      std::vector<Arc> ipath;
1666
      findInternalPath(ipath, wnode, root, type_map, order_map,
1667
                       node_data, arc_lists);
1668
      setInternalFlags(ipath, type_map);
1669
      pynode = _graph.source(ipath.front());
1670
      pxnode = _graph.target(ipath.back());
1671

	
1672
      wnode = findPertinent(pynode, order_map, node_data,
1673
                            embed_arc, merge_roots);
1674

	
1675
      // Minor-C
1676
      {
1677
        if (type_map[_graph.source(ipath.front())] == HIGHY) {
1678
          if (type_map[_graph.target(ipath.back())] == HIGHX) {
1679
            markFacePath(xnode, pxnode, order_map, node_data);
1680
          }
1681
          markFacePath(root, xnode, order_map, node_data);
1682
          markPertinentPath(wnode, order_map, node_data, arc_lists,
1683
                            embed_arc, merge_roots);
1684
          markInternalPath(ipath);
1685
          int xlp = markExternalPath(xnode, order_map, child_lists,
1686
                                     pred_map, ancestor_map, low_map);
1687
          int ylp = markExternalPath(ynode, order_map, child_lists,
1688
                                     pred_map, ancestor_map, low_map);
1689
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1690
          return;
1691
        }
1692

	
1693
        if (type_map[_graph.target(ipath.back())] == HIGHX) {
1694
          markFacePath(ynode, root, order_map, node_data);
1695
          markPertinentPath(wnode, order_map, node_data, arc_lists,
1696
                            embed_arc, merge_roots);
1697
          markInternalPath(ipath);
1698
          int xlp = markExternalPath(xnode, order_map, child_lists,
1699
                                     pred_map, ancestor_map, low_map);
1700
          int ylp = markExternalPath(ynode, order_map, child_lists,
1701
                                     pred_map, ancestor_map, low_map);
1702
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1703
          return;
1704
        }
1705
      }
1706

	
1707
      std::vector<Arc> ppath;
1708
      findPilePath(ppath, root, type_map, order_map, node_data, arc_lists);
1709

	
1710
      // Minor-D
1711
      if (!ppath.empty()) {
1712
        markFacePath(ynode, xnode, order_map, node_data);
1713
        markPertinentPath(wnode, order_map, node_data, arc_lists,
1714
                          embed_arc, merge_roots);
1715
        markPilePath(ppath);
1716
        markInternalPath(ipath);
1717
        int xlp = markExternalPath(xnode, order_map, child_lists,
1718
                                   pred_map, ancestor_map, low_map);
1719
        int ylp = markExternalPath(ynode, order_map, child_lists,
1720
                                   pred_map, ancestor_map, low_map);
1721
        markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1722
        return;
1723
      }
1724

	
1725
      // Minor-E*
1726
      {
1727

	
1728
        if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1729
          Node znode = findExternal(pynode, rorder, order_map,
1730
                                    child_lists, ancestor_map,
1731
                                    low_map, node_data);
1732

	
1733
          if (type_map[znode] == LOWY) {
1734
            markFacePath(root, xnode, order_map, node_data);
1735
            markPertinentPath(wnode, order_map, node_data, arc_lists,
1736
                              embed_arc, merge_roots);
1737
            markInternalPath(ipath);
1738
            int xlp = markExternalPath(xnode, order_map, child_lists,
1739
                                       pred_map, ancestor_map, low_map);
1740
            int zlp = markExternalPath(znode, order_map, child_lists,
1741
                                       pred_map, ancestor_map, low_map);
1742
            markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
1743
          } else {
1744
            markFacePath(ynode, root, order_map, node_data);
1745
            markPertinentPath(wnode, order_map, node_data, arc_lists,
1746
                              embed_arc, merge_roots);
1747
            markInternalPath(ipath);
1748
            int ylp = markExternalPath(ynode, order_map, child_lists,
1749
                                       pred_map, ancestor_map, low_map);
1750
            int zlp = markExternalPath(znode, order_map, child_lists,
1751
                                       pred_map, ancestor_map, low_map);
1752
            markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
1753
          }
1754
          return;
1755
        }
1756

	
1757
        int xlp = markExternalPath(xnode, order_map, child_lists,
1758
                                   pred_map, ancestor_map, low_map);
1759
        int ylp = markExternalPath(ynode, order_map, child_lists,
1760
                                   pred_map, ancestor_map, low_map);
1761
        int wlp = markExternalPath(wnode, order_map, child_lists,
1762
                                   pred_map, ancestor_map, low_map);
1763

	
1764
        if (wlp > xlp && wlp > ylp) {
1765
          markFacePath(root, root, order_map, node_data);
1766
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1767
          return;
1768
        }
1769

	
1770
        markInternalPath(ipath);
1771
        markPertinentPath(wnode, order_map, node_data, arc_lists,
1772
                          embed_arc, merge_roots);
1773

	
1774
        if (xlp > ylp && xlp > wlp) {
1775
          markFacePath(root, pynode, order_map, node_data);
1776
          markFacePath(wnode, xnode, order_map, node_data);
1777
          markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
1778
          return;
1779
        }
1780

	
1781
        if (ylp > xlp && ylp > wlp) {
1782
          markFacePath(pxnode, root, order_map, node_data);
1783
          markFacePath(ynode, wnode, order_map, node_data);
1784
          markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
1785
          return;
1786
        }
1787

	
1788
        if (pynode != ynode) {
1789
          markFacePath(pxnode, wnode, order_map, node_data);
1790

	
1791
          int minlp = xlp < ylp ? xlp : ylp;
1792
          if (wlp < minlp) minlp = wlp;
1793

	
1794
          int maxlp = xlp > ylp ? xlp : ylp;
1795
          if (wlp > maxlp) maxlp = wlp;
1796

	
1797
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1798
          return;
1799
        }
1800

	
1801
        if (pxnode != xnode) {
1802
          markFacePath(wnode, pynode, order_map, node_data);
1803

	
1804
          int minlp = xlp < ylp ? xlp : ylp;
1805
          if (wlp < minlp) minlp = wlp;
1806

	
1807
          int maxlp = xlp > ylp ? xlp : ylp;
1808
          if (wlp > maxlp) maxlp = wlp;
1809

	
1810
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1811
          return;
1812
        }
1813

	
1814
        markFacePath(root, root, order_map, node_data);
1815
        int minlp = xlp < ylp ? xlp : ylp;
1816
        if (wlp < minlp) minlp = wlp;
1817
        markPredPath(root, order_list[minlp], pred_map);
1818
        return;
1819
      }
1820

	
1821
    }
1822

	
1823
  };
1824

	
1825
  namespace _planarity_bits {
1826

	
1827
    template <typename Graph, typename EmbeddingMap>
1828
    void makeConnected(Graph& graph, EmbeddingMap& embedding) {
1829
      DfsVisitor<Graph> null_visitor;
1830
      DfsVisit<Graph, DfsVisitor<Graph> > dfs(graph, null_visitor);
1831
      dfs.init();
1832

	
1833
      typename Graph::Node u = INVALID;
1834
      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1835
        if (!dfs.reached(n)) {
1836
          dfs.addSource(n);
1837
          dfs.start();
1838
          if (u == INVALID) {
1839
            u = n;
1840
          } else {
1841
            typename Graph::Node v = n;
1842

	
1843
            typename Graph::Arc ue = typename Graph::OutArcIt(graph, u);
1844
            typename Graph::Arc ve = typename Graph::OutArcIt(graph, v);
1845

	
1846
            typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true);
1847

	
1848
            if (ue != INVALID) {
1849
              embedding[e] = embedding[ue];
1850
              embedding[ue] = e;
1851
            } else {
1852
              embedding[e] = e;
1853
            }
1854

	
1855
            if (ve != INVALID) {
1856
              embedding[graph.oppositeArc(e)] = embedding[ve];
1857
              embedding[ve] = graph.oppositeArc(e);
1858
            } else {
1859
              embedding[graph.oppositeArc(e)] = graph.oppositeArc(e);
1860
            }
1861
          }
1862
        }
1863
      }
1864
    }
1865

	
1866
    template <typename Graph, typename EmbeddingMap>
1867
    void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) {
1868
      typename Graph::template ArcMap<bool> processed(graph);
1869

	
1870
      std::vector<typename Graph::Arc> arcs;
1871
      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
1872
        arcs.push_back(e);
1873
      }
1874

	
1875
      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
1876

	
1877
      for (int i = 0; i < int(arcs.size()); ++i) {
1878
        typename Graph::Arc pp = arcs[i];
1879
        if (processed[pp]) continue;
1880

	
1881
        typename Graph::Arc e = embedding[graph.oppositeArc(pp)];
1882
        processed[e] = true;
1883
        visited.set(graph.source(e), true);
1884

	
1885
        typename Graph::Arc p = e, l = e;
1886
        e = embedding[graph.oppositeArc(e)];
1887

	
1888
        while (e != l) {
1889
          processed[e] = true;
1890

	
1891
          if (visited[graph.source(e)]) {
1892

	
1893
            typename Graph::Arc n =
1894
              graph.direct(graph.addEdge(graph.source(p),
1895
                                           graph.target(e)), true);
1896
            embedding[n] = p;
1897
            embedding[graph.oppositeArc(pp)] = n;
1898

	
1899
            embedding[graph.oppositeArc(n)] =
1900
              embedding[graph.oppositeArc(e)];
1901
            embedding[graph.oppositeArc(e)] =
1902
              graph.oppositeArc(n);
1903

	
1904
            p = n;
1905
            e = embedding[graph.oppositeArc(n)];
1906
          } else {
1907
            visited.set(graph.source(e), true);
1908
            pp = p;
1909
            p = e;
1910
            e = embedding[graph.oppositeArc(e)];
1911
          }
1912
        }
1913
        visited.setAll(false);
1914
      }
1915
    }
1916

	
1917

	
1918
    template <typename Graph, typename EmbeddingMap>
1919
    void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) {
1920

	
1921
      typename Graph::template NodeMap<int> degree(graph);
1922

	
1923
      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1924
        degree[n] = countIncEdges(graph, n);
1925
      }
1926

	
1927
      typename Graph::template ArcMap<bool> processed(graph);
1928
      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
1929

	
1930
      std::vector<typename Graph::Arc> arcs;
1931
      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
1932
        arcs.push_back(e);
1933
      }
1934

	
1935
      for (int i = 0; i < int(arcs.size()); ++i) {
1936
        typename Graph::Arc e = arcs[i];
1937

	
1938
        if (processed[e]) continue;
1939
        processed[e] = true;
1940

	
1941
        typename Graph::Arc mine = e;
1942
        int mind = degree[graph.source(e)];
1943

	
1944
        int face_size = 1;
1945

	
1946
        typename Graph::Arc l = e;
1947
        e = embedding[graph.oppositeArc(e)];
1948
        while (l != e) {
1949
          processed[e] = true;
1950

	
1951
          ++face_size;
1952

	
1953
          if (degree[graph.source(e)] < mind) {
1954
            mine = e;
1955
            mind = degree[graph.source(e)];
1956
          }
1957

	
1958
          e = embedding[graph.oppositeArc(e)];
1959
        }
1960

	
1961
        if (face_size < 4) {
1962
          continue;
1963
        }
1964

	
1965
        typename Graph::Node s = graph.source(mine);
1966
        for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) {
1967
          visited.set(graph.target(e), true);
1968
        }
1969

	
1970
        typename Graph::Arc oppe = INVALID;
1971

	
1972
        e = embedding[graph.oppositeArc(mine)];
1973
        e = embedding[graph.oppositeArc(e)];
1974
        while (graph.target(e) != s) {
1975
          if (visited[graph.source(e)]) {
1976
            oppe = e;
1977
            break;
1978
          }
1979
          e = embedding[graph.oppositeArc(e)];
1980
        }
1981
        visited.setAll(false);
1982

	
1983
        if (oppe == INVALID) {
1984

	
1985
          e = embedding[graph.oppositeArc(mine)];
1986
          typename Graph::Arc pn = mine, p = e;
1987

	
1988
          e = embedding[graph.oppositeArc(e)];
1989
          while (graph.target(e) != s) {
1990
            typename Graph::Arc n =
1991
              graph.direct(graph.addEdge(s, graph.source(e)), true);
1992

	
1993
            embedding[n] = pn;
1994
            embedding[graph.oppositeArc(n)] = e;
1995
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
1996

	
1997
            pn = n;
1998

	
1999
            p = e;
2000
            e = embedding[graph.oppositeArc(e)];
2001
          }
2002

	
2003
          embedding[graph.oppositeArc(e)] = pn;
2004

	
2005
        } else {
2006

	
2007
          mine = embedding[graph.oppositeArc(mine)];
2008
          s = graph.source(mine);
2009
          oppe = embedding[graph.oppositeArc(oppe)];
2010
          typename Graph::Node t = graph.source(oppe);
2011

	
2012
          typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true);
2013
          embedding[ce] = mine;
2014
          embedding[graph.oppositeArc(ce)] = oppe;
2015

	
2016
          typename Graph::Arc pn = ce, p = oppe;
2017
          e = embedding[graph.oppositeArc(oppe)];
2018
          while (graph.target(e) != s) {
2019
            typename Graph::Arc n =
2020
              graph.direct(graph.addEdge(s, graph.source(e)), true);
2021

	
2022
            embedding[n] = pn;
2023
            embedding[graph.oppositeArc(n)] = e;
2024
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
2025

	
2026
            pn = n;
2027

	
2028
            p = e;
2029
            e = embedding[graph.oppositeArc(e)];
2030

	
2031
          }
2032
          embedding[graph.oppositeArc(e)] = pn;
2033

	
2034
          pn = graph.oppositeArc(ce), p = mine;
2035
          e = embedding[graph.oppositeArc(mine)];
2036
          while (graph.target(e) != t) {
2037
            typename Graph::Arc n =
2038
              graph.direct(graph.addEdge(t, graph.source(e)), true);
2039

	
2040
            embedding[n] = pn;
2041
            embedding[graph.oppositeArc(n)] = e;
2042
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
2043

	
2044
            pn = n;
2045

	
2046
            p = e;
2047
            e = embedding[graph.oppositeArc(e)];
2048

	
2049
          }
2050
          embedding[graph.oppositeArc(e)] = pn;
2051
        }
2052
      }
2053
    }
2054

	
2055
  }
2056

	
2057
  /// \ingroup planar
2058
  ///
2059
  /// \brief Schnyder's planar drawing algorithm
2060
  ///
2061
  /// The planar drawing algorithm calculates positions for the nodes
2062
  /// in the plane which coordinates satisfy that if the arcs are
2063
  /// represented with straight lines then they will not intersect
2064
  /// each other.
2065
  ///
2066
  /// Scnyder's algorithm embeds the graph on \c (n-2,n-2) size grid,
2067
  /// i.e. each node will be located in the \c [0,n-2]x[0,n-2] square.
2068
  /// The time complexity of the algorithm is O(n).
2069
  template <typename Graph>
2070
  class PlanarDrawing {
2071
  public:
2072

	
2073
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2074

	
2075
    /// \brief The point type for store coordinates
2076
    typedef dim2::Point<int> Point;
2077
    /// \brief The map type for store coordinates
2078
    typedef typename Graph::template NodeMap<Point> PointMap;
2079

	
2080

	
2081
    /// \brief Constructor
2082
    ///
2083
    /// Constructor
2084
    /// \pre The graph should be simple, i.e. loop and parallel arc free.
2085
    PlanarDrawing(const Graph& graph)
2086
      : _graph(graph), _point_map(graph) {}
2087

	
2088
  private:
2089

	
2090
    template <typename AuxGraph, typename AuxEmbeddingMap>
2091
    void drawing(const AuxGraph& graph,
2092
                 const AuxEmbeddingMap& next,
2093
                 PointMap& point_map) {
2094
      TEMPLATE_GRAPH_TYPEDEFS(AuxGraph);
2095

	
2096
      typename AuxGraph::template ArcMap<Arc> prev(graph);
2097

	
2098
      for (NodeIt n(graph); n != INVALID; ++n) {
2099
        Arc e = OutArcIt(graph, n);
2100

	
2101
        Arc p = e, l = e;
2102

	
2103
        e = next[e];
2104
        while (e != l) {
2105
          prev[e] = p;
2106
          p = e;
2107
          e = next[e];
2108
        }
2109
        prev[e] = p;
2110
      }
2111

	
2112
      Node anode, bnode, cnode;
2113

	
2114
      {
2115
        Arc e = ArcIt(graph);
2116
        anode = graph.source(e);
2117
        bnode = graph.target(e);
2118
        cnode = graph.target(next[graph.oppositeArc(e)]);
2119
      }
2120

	
2121
      IterableBoolMap<AuxGraph, Node> proper(graph, false);
2122
      typename AuxGraph::template NodeMap<int> conn(graph, -1);
2123

	
2124
      conn[anode] = conn[bnode] = -2;
2125
      {
2126
        for (OutArcIt e(graph, anode); e != INVALID; ++e) {
2127
          Node m = graph.target(e);
2128
          if (conn[m] == -1) {
2129
            conn[m] = 1;
2130
          }
2131
        }
2132
        conn[cnode] = 2;
2133

	
2134
        for (OutArcIt e(graph, bnode); e != INVALID; ++e) {
2135
          Node m = graph.target(e);
2136
          if (conn[m] == -1) {
2137
            conn[m] = 1;
2138
          } else if (conn[m] != -2) {
2139
            conn[m] += 1;
2140
            Arc pe = graph.oppositeArc(e);
2141
            if (conn[graph.target(next[pe])] == -2) {
2142
              conn[m] -= 1;
2143
            }
2144
            if (conn[graph.target(prev[pe])] == -2) {
2145
              conn[m] -= 1;
2146
            }
2147

	
2148
            proper.set(m, conn[m] == 1);
2149
          }
2150
        }
2151
      }
2152

	
2153

	
2154
      typename AuxGraph::template ArcMap<int> angle(graph, -1);
2155

	
2156
      while (proper.trueNum() != 0) {
2157
        Node n = typename IterableBoolMap<AuxGraph, Node>::TrueIt(proper);
2158
        proper.set(n, false);
2159
        conn[n] = -2;
2160

	
2161
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2162
          Node m = graph.target(e);
2163
          if (conn[m] == -1) {
2164
            conn[m] = 1;
2165
          } else if (conn[m] != -2) {
2166
            conn[m] += 1;
2167
            Arc pe = graph.oppositeArc(e);
2168
            if (conn[graph.target(next[pe])] == -2) {
2169
              conn[m] -= 1;
2170
            }
2171
            if (conn[graph.target(prev[pe])] == -2) {
2172
              conn[m] -= 1;
2173
            }
2174

	
2175
            proper.set(m, conn[m] == 1);
2176
          }
2177
        }
2178

	
2179
        {
2180
          Arc e = OutArcIt(graph, n);
2181
          Arc p = e, l = e;
2182

	
2183
          e = next[e];
2184
          while (e != l) {
2185

	
2186
            if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
2187
              Arc f = e;
2188
              angle[f] = 0;
2189
              f = next[graph.oppositeArc(f)];
2190
              angle[f] = 1;
2191
              f = next[graph.oppositeArc(f)];
2192
              angle[f] = 2;
2193
            }
2194

	
2195
            p = e;
2196
            e = next[e];
2197
          }
2198

	
2199
          if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
2200
            Arc f = e;
2201
            angle[f] = 0;
2202
            f = next[graph.oppositeArc(f)];
2203
            angle[f] = 1;
2204
            f = next[graph.oppositeArc(f)];
2205
            angle[f] = 2;
2206
          }
2207
        }
2208
      }
2209

	
2210
      typename AuxGraph::template NodeMap<Node> apred(graph, INVALID);
2211
      typename AuxGraph::template NodeMap<Node> bpred(graph, INVALID);
2212
      typename AuxGraph::template NodeMap<Node> cpred(graph, INVALID);
2213

	
2214
      typename AuxGraph::template NodeMap<int> apredid(graph, -1);
2215
      typename AuxGraph::template NodeMap<int> bpredid(graph, -1);
2216
      typename AuxGraph::template NodeMap<int> cpredid(graph, -1);
2217

	
2218
      for (ArcIt e(graph); e != INVALID; ++e) {
2219
        if (angle[e] == angle[next[e]]) {
2220
          switch (angle[e]) {
2221
          case 2:
2222
            apred[graph.target(e)] = graph.source(e);
2223
            apredid[graph.target(e)] = graph.id(graph.source(e));
2224
            break;
2225
          case 1:
2226
            bpred[graph.target(e)] = graph.source(e);
2227
            bpredid[graph.target(e)] = graph.id(graph.source(e));
2228
            break;
2229
          case 0:
2230
            cpred[graph.target(e)] = graph.source(e);
2231
            cpredid[graph.target(e)] = graph.id(graph.source(e));
2232
            break;
2233
          }
2234
        }
2235
      }
2236

	
2237
      cpred[anode] = INVALID;
2238
      cpred[bnode] = INVALID;
2239

	
2240
      std::vector<Node> aorder, border, corder;
2241

	
2242
      {
2243
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2244
        std::vector<Node> st;
2245
        for (NodeIt n(graph); n != INVALID; ++n) {
2246
          if (!processed[n] && n != bnode && n != cnode) {
2247
            st.push_back(n);
2248
            processed[n] = true;
2249
            Node m = apred[n];
2250
            while (m != INVALID && !processed[m]) {
2251
              st.push_back(m);
2252
              processed[m] = true;
2253
              m = apred[m];
2254
            }
2255
            while (!st.empty()) {
2256
              aorder.push_back(st.back());
2257
              st.pop_back();
2258
            }
2259
          }
2260
        }
2261
      }
2262

	
2263
      {
2264
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2265
        std::vector<Node> st;
2266
        for (NodeIt n(graph); n != INVALID; ++n) {
2267
          if (!processed[n] && n != cnode && n != anode) {
2268
            st.push_back(n);
2269
            processed[n] = true;
2270
            Node m = bpred[n];
2271
            while (m != INVALID && !processed[m]) {
2272
              st.push_back(m);
2273
              processed[m] = true;
2274
              m = bpred[m];
2275
            }
2276
            while (!st.empty()) {
2277
              border.push_back(st.back());
2278
              st.pop_back();
2279
            }
2280
          }
2281
        }
2282
      }
2283

	
2284
      {
2285
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2286
        std::vector<Node> st;
2287
        for (NodeIt n(graph); n != INVALID; ++n) {
2288
          if (!processed[n] && n != anode && n != bnode) {
2289
            st.push_back(n);
2290
            processed[n] = true;
2291
            Node m = cpred[n];
2292
            while (m != INVALID && !processed[m]) {
2293
              st.push_back(m);
2294
              processed[m] = true;
2295
              m = cpred[m];
2296
            }
2297
            while (!st.empty()) {
2298
              corder.push_back(st.back());
2299
              st.pop_back();
2300
            }
2301
          }
2302
        }
2303
      }
2304

	
2305
      typename AuxGraph::template NodeMap<int> atree(graph, 0);
2306
      for (int i = aorder.size() - 1; i >= 0; --i) {
2307
        Node n = aorder[i];
2308
        atree[n] = 1;
2309
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2310
          if (apred[graph.target(e)] == n) {
2311
            atree[n] += atree[graph.target(e)];
2312
          }
2313
        }
2314
      }
2315

	
2316
      typename AuxGraph::template NodeMap<int> btree(graph, 0);
2317
      for (int i = border.size() - 1; i >= 0; --i) {
2318
        Node n = border[i];
2319
        btree[n] = 1;
2320
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2321
          if (bpred[graph.target(e)] == n) {
2322
            btree[n] += btree[graph.target(e)];
2323
          }
2324
        }
2325
      }
2326

	
2327
      typename AuxGraph::template NodeMap<int> apath(graph, 0);
2328
      apath[bnode] = apath[cnode] = 1;
2329
      typename AuxGraph::template NodeMap<int> apath_btree(graph, 0);
2330
      apath_btree[bnode] = btree[bnode];
2331
      for (int i = 1; i < int(aorder.size()); ++i) {
2332
        Node n = aorder[i];
2333
        apath[n] = apath[apred[n]] + 1;
2334
        apath_btree[n] = btree[n] + apath_btree[apred[n]];
2335
      }
2336

	
2337
      typename AuxGraph::template NodeMap<int> bpath_atree(graph, 0);
2338
      bpath_atree[anode] = atree[anode];
2339
      for (int i = 1; i < int(border.size()); ++i) {
2340
        Node n = border[i];
2341
        bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
2342
      }
2343

	
2344
      typename AuxGraph::template NodeMap<int> cpath(graph, 0);
2345
      cpath[anode] = cpath[bnode] = 1;
2346
      typename AuxGraph::template NodeMap<int> cpath_atree(graph, 0);
2347
      cpath_atree[anode] = atree[anode];
2348
      typename AuxGraph::template NodeMap<int> cpath_btree(graph, 0);
2349
      cpath_btree[bnode] = btree[bnode];
2350
      for (int i = 1; i < int(corder.size()); ++i) {
2351
        Node n = corder[i];
2352
        cpath[n] = cpath[cpred[n]] + 1;
2353
        cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
2354
        cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
2355
      }
2356

	
2357
      typename AuxGraph::template NodeMap<int> third(graph);
2358
      for (NodeIt n(graph); n != INVALID; ++n) {
2359
        point_map[n].x =
2360
          bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
2361
        point_map[n].y =
2362
          cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
2363
      }
2364

	
2365
    }
2366

	
2367
  public:
2368

	
2369
    /// \brief Calculates the node positions
2370
    ///
2371
    /// This function calculates the node positions.
2372
    /// \return %True if the graph is planar.
2373
    bool run() {
2374
      PlanarEmbedding<Graph> pe(_graph);
2375
      if (!pe.run()) return false;
2376

	
2377
      run(pe);
2378
      return true;
2379
    }
2380

	
2381
    /// \brief Calculates the node positions according to a
2382
    /// combinatorical embedding
2383
    ///
2384
    /// This function calculates the node locations. The \c embedding
2385
    /// parameter should contain a valid combinatorical embedding, i.e.
2386
    /// a valid cyclic order of the arcs.
2387
    template <typename EmbeddingMap>
2388
    void run(const EmbeddingMap& embedding) {
2389
      typedef SmartEdgeSet<Graph> AuxGraph;
2390

	
2391
      if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
2392
        drawing(_graph, embedding, _point_map);
2393
        return;
2394
      }
2395

	
2396
      AuxGraph aux_graph(_graph);
2397
      typename AuxGraph::template ArcMap<typename AuxGraph::Arc>
2398
        aux_embedding(aux_graph);
2399

	
2400
      {
2401

	
2402
        typename Graph::template EdgeMap<typename AuxGraph::Edge>
2403
          ref(_graph);
2404

	
2405
        for (EdgeIt e(_graph); e != INVALID; ++e) {
2406
          ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e));
2407
        }
2408

	
2409
        for (EdgeIt e(_graph); e != INVALID; ++e) {
2410
          Arc ee = embedding[_graph.direct(e, true)];
2411
          aux_embedding[aux_graph.direct(ref[e], true)] =
2412
            aux_graph.direct(ref[ee], _graph.direction(ee));
2413
          ee = embedding[_graph.direct(e, false)];
2414
          aux_embedding[aux_graph.direct(ref[e], false)] =
2415
            aux_graph.direct(ref[ee], _graph.direction(ee));
2416
        }
2417
      }
2418
      _planarity_bits::makeConnected(aux_graph, aux_embedding);
2419
      _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding);
2420
      _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding);
2421
      drawing(aux_graph, aux_embedding, _point_map);
2422
    }
2423

	
2424
    /// \brief The coordinate of the given node
2425
    ///
2426
    /// The coordinate of the given node.
2427
    Point operator[](const Node& node) const {
2428
      return _point_map[node];
2429
    }
2430

	
2431
    /// \brief Returns the grid embedding in a \e NodeMap.
2432
    ///
2433
    /// Returns the grid embedding in a \e NodeMap of \c dim2::Point<int> .
2434
    const PointMap& coords() const {
2435
      return _point_map;
2436
    }
2437

	
2438
  private:
2439

	
2440
    const Graph& _graph;
2441
    PointMap _point_map;
2442

	
2443
  };
2444

	
2445
  namespace _planarity_bits {
2446

	
2447
    template <typename ColorMap>
2448
    class KempeFilter {
2449
    public:
2450
      typedef typename ColorMap::Key Key;
2451
      typedef bool Value;
2452

	
2453
      KempeFilter(const ColorMap& color_map,
2454
                  const typename ColorMap::Value& first,
2455
                  const typename ColorMap::Value& second)
2456
        : _color_map(color_map), _first(first), _second(second) {}
2457

	
2458
      Value operator[](const Key& key) const {
2459
        return _color_map[key] == _first || _color_map[key] == _second;
2460
      }
2461

	
2462
    private:
2463
      const ColorMap& _color_map;
2464
      typename ColorMap::Value _first, _second;
2465
    };
2466
  }
2467

	
2468
  /// \ingroup planar
2469
  ///
2470
  /// \brief Coloring planar graphs
2471
  ///
2472
  /// The graph coloring problem is the coloring of the graph nodes
2473
  /// that there are not adjacent nodes with the same color. The
2474
  /// planar graphs can be always colored with four colors, it is
2475
  /// proved by Appel and Haken and their proofs provide a quadratic
2476
  /// time algorithm for four coloring, but it could not be used to
2477
  /// implement efficient algorithm. The five and six coloring can be
2478
  /// made in linear time, but in this class the five coloring has
2479
  /// quadratic worst case time complexity. The two coloring (if
2480
  /// possible) is solvable with a graph search algorithm and it is
2481
  /// implemented in \ref bipartitePartitions() function in LEMON. To
2482
  /// decide whether the planar graph is three colorable is
2483
  /// NP-complete.
2484
  ///
2485
  /// This class contains member functions for calculate colorings
2486
  /// with five and six colors. The six coloring algorithm is a simple
2487
  /// greedy coloring on the backward minimum outgoing order of nodes.
2488
  /// This order can be computed as in each phase the node with least
2489
  /// outgoing arcs to unprocessed nodes is chosen. This order
2490
  /// guarantees that when a node is chosen for coloring it has at
2491
  /// most five already colored adjacents. The five coloring algorithm
2492
  /// use the same method, but if the greedy approach fails to color
2493
  /// with five colors, i.e. the node has five already different
2494
  /// colored neighbours, it swaps the colors in one of the connected
2495
  /// two colored sets with the Kempe recoloring method.
2496
  template <typename Graph>
2497
  class PlanarColoring {
2498
  public:
2499

	
2500
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2501

	
2502
    /// \brief The map type for store color indexes
2503
    typedef typename Graph::template NodeMap<int> IndexMap;
2504
    /// \brief The map type for store colors
2505
    typedef ComposeMap<Palette, IndexMap> ColorMap;
2506

	
2507
    /// \brief Constructor
2508
    ///
2509
    /// Constructor
2510
    /// \pre The graph should be simple, i.e. loop and parallel arc free.
2511
    PlanarColoring(const Graph& graph)
2512
      : _graph(graph), _color_map(graph), _palette(0) {
2513
      _palette.add(Color(1,0,0));
2514
      _palette.add(Color(0,1,0));
2515
      _palette.add(Color(0,0,1));
2516
      _palette.add(Color(1,1,0));
2517
      _palette.add(Color(1,0,1));
2518
      _palette.add(Color(0,1,1));
2519
    }
2520

	
2521
    /// \brief Returns the \e NodeMap of color indexes
2522
    ///
2523
    /// Returns the \e NodeMap of color indexes. The values are in the
2524
    /// range \c [0..4] or \c [0..5] according to the coloring method.
2525
    IndexMap colorIndexMap() const {
2526
      return _color_map;
2527
    }
2528

	
2529
    /// \brief Returns the \e NodeMap of colors
2530
    ///
2531
    /// Returns the \e NodeMap of colors. The values are five or six
2532
    /// distinct \ref lemon::Color "colors".
2533
    ColorMap colorMap() const {
2534
      return composeMap(_palette, _color_map);
2535
    }
2536

	
2537
    /// \brief Returns the color index of the node
2538
    ///
2539
    /// Returns the color index of the node. The values are in the
2540
    /// range \c [0..4] or \c [0..5] according to the coloring method.
2541
    int colorIndex(const Node& node) const {
2542
      return _color_map[node];
2543
    }
2544

	
2545
    /// \brief Returns the color of the node
2546
    ///
2547
    /// Returns the color of the node. The values are five or six
2548
    /// distinct \ref lemon::Color "colors".
2549
    Color color(const Node& node) const {
2550
      return _palette[_color_map[node]];
2551
    }
2552

	
2553

	
2554
    /// \brief Calculates a coloring with at most six colors
2555
    ///
2556
    /// This function calculates a coloring with at most six colors. The time
2557
    /// complexity of this variant is linear in the size of the graph.
2558
    /// \return %True when the algorithm could color the graph with six color.
2559
    /// If the algorithm fails, then the graph could not be planar.
2560
    /// \note This function can return true if the graph is not
2561
    /// planar but it can be colored with 6 colors.
2562
    bool runSixColoring() {
2563

	
2564
      typename Graph::template NodeMap<int> heap_index(_graph, -1);
2565
      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
2566

	
2567
      for (NodeIt n(_graph); n != INVALID; ++n) {
2568
        _color_map[n] = -2;
2569
        heap.push(n, countOutArcs(_graph, n));
2570
      }
2571

	
2572
      std::vector<Node> order;
2573

	
2574
      while (!heap.empty()) {
2575
        Node n = heap.top();
2576
        heap.pop();
2577
        _color_map[n] = -1;
2578
        order.push_back(n);
2579
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2580
          Node t = _graph.runningNode(e);
2581
          if (_color_map[t] == -2) {
2582
            heap.decrease(t, heap[t] - 1);
2583
          }
2584
        }
2585
      }
2586

	
2587
      for (int i = order.size() - 1; i >= 0; --i) {
2588
        std::vector<bool> forbidden(6, false);
2589
        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
2590
          Node t = _graph.runningNode(e);
2591
          if (_color_map[t] != -1) {
2592
            forbidden[_color_map[t]] = true;
2593
          }
2594
        }
2595
               for (int k = 0; k < 6; ++k) {
2596
          if (!forbidden[k]) {
2597
            _color_map[order[i]] = k;
2598
            break;
2599
          }
2600
        }
2601
        if (_color_map[order[i]] == -1) {
2602
          return false;
2603
        }
2604
      }
2605
      return true;
2606
    }
2607

	
2608
  private:
2609

	
2610
    bool recolor(const Node& u, const Node& v) {
2611
      int ucolor = _color_map[u];
2612
      int vcolor = _color_map[v];
2613
      typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
2614
      KempeFilter filter(_color_map, ucolor, vcolor);
2615

	
2616
      typedef FilterNodes<const Graph, const KempeFilter> KempeGraph;
2617
      KempeGraph kempe_graph(_graph, filter);
2618

	
2619
      std::vector<Node> comp;
2620
      Bfs<KempeGraph> bfs(kempe_graph);
2621
      bfs.init();
2622
      bfs.addSource(u);
2623
      while (!bfs.emptyQueue()) {
2624
        Node n = bfs.nextNode();
2625
        if (n == v) return false;
2626
        comp.push_back(n);
2627
        bfs.processNextNode();
2628
      }
2629

	
2630
      int scolor = ucolor + vcolor;
2631
      for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
2632
        _color_map[comp[i]] = scolor - _color_map[comp[i]];
2633
      }
2634

	
2635
      return true;
2636
    }
2637

	
2638
    template <typename EmbeddingMap>
2639
    void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
2640
      std::vector<Node> nodes;
2641
      nodes.reserve(4);
2642

	
2643
      for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) {
2644
        Node t = _graph.target(e);
2645
        if (_color_map[t] != -1) {
2646
          nodes.push_back(t);
2647
          if (nodes.size() == 4) break;
2648
        }
2649
      }
2650

	
2651
      int color = _color_map[nodes[0]];
2652
      if (recolor(nodes[0], nodes[2])) {
2653
        _color_map[node] = color;
2654
      } else {
2655
        color = _color_map[nodes[1]];
2656
        recolor(nodes[1], nodes[3]);
2657
        _color_map[node] = color;
2658
      }
2659
    }
2660

	
2661
  public:
2662

	
2663
    /// \brief Calculates a coloring with at most five colors
2664
    ///
2665
    /// This function calculates a coloring with at most five
2666
    /// colors. The worst case time complexity of this variant is
2667
    /// quadratic in the size of the graph.
2668
    template <typename EmbeddingMap>
2669
    void runFiveColoring(const EmbeddingMap& embedding) {
2670

	
2671
      typename Graph::template NodeMap<int> heap_index(_graph, -1);
2672
      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
2673

	
2674
      for (NodeIt n(_graph); n != INVALID; ++n) {
2675
        _color_map[n] = -2;
2676
        heap.push(n, countOutArcs(_graph, n));
2677
      }
2678

	
2679
      std::vector<Node> order;
2680

	
2681
      while (!heap.empty()) {
2682
        Node n = heap.top();
2683
        heap.pop();
2684
        _color_map[n] = -1;
2685
        order.push_back(n);
2686
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2687
          Node t = _graph.runningNode(e);
2688
          if (_color_map[t] == -2) {
2689
            heap.decrease(t, heap[t] - 1);
2690
          }
2691
        }
2692
      }
2693

	
2694
      for (int i = order.size() - 1; i >= 0; --i) {
2695
        std::vector<bool> forbidden(5, false);
2696
        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
2697
          Node t = _graph.runningNode(e);
2698
          if (_color_map[t] != -1) {
2699
            forbidden[_color_map[t]] = true;
2700
          }
2701
        }
2702
        for (int k = 0; k < 5; ++k) {
2703
          if (!forbidden[k]) {
2704
            _color_map[order[i]] = k;
2705
            break;
2706
          }
2707
        }
2708
        if (_color_map[order[i]] == -1) {
2709
          kempeRecoloring(order[i], embedding);
2710
        }
2711
      }
2712
    }
2713

	
2714
    /// \brief Calculates a coloring with at most five colors
2715
    ///
2716
    /// This function calculates a coloring with at most five
2717
    /// colors. The worst case time complexity of this variant is
2718
    /// quadratic in the size of the graph.
2719
    /// \return %True when the graph is planar.
2720
    bool runFiveColoring() {
2721
      PlanarEmbedding<Graph> pe(_graph);
2722
      if (!pe.run()) return false;
2723

	
2724
      runFiveColoring(pe.embeddingMap());
2725
      return true;
2726
    }
2727

	
2728
  private:
2729

	
2730
    const Graph& _graph;
2731
    IndexMap _color_map;
2732
    Palette _palette;
2733
  };
2734

	
2735
}
2736

	
2737
#endif
Ignore white space 6 line context
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-2009
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
#include <iostream>
20

	
21
#include <lemon/planarity.h>
22

	
23
#include <lemon/smart_graph.h>
24
#include <lemon/lgf_reader.h>
25
#include <lemon/connectivity.h>
26
#include <lemon/dim2.h>
27

	
28
#include "test_tools.h"
29

	
30
using namespace lemon;
31
using namespace lemon::dim2;
32

	
33
const int lgfn = 4;
34
const std::string lgf[lgfn] = {
35
  "@nodes\n"
36
  "label\n"
37
  "0\n"
38
  "1\n"
39
  "2\n"
40
  "3\n"
41
  "4\n"
42
  "@edges\n"
43
  "     label\n"
44
  "0 1  0\n"
45
  "0 2  0\n"
46
  "0 3  0\n"
47
  "0 4  0\n"
48
  "1 2  0\n"
49
  "1 3  0\n"
50
  "1 4  0\n"
51
  "2 3  0\n"
52
  "2 4  0\n"
53
  "3 4  0\n",
54

	
55
  "@nodes\n"
56
  "label\n"
57
  "0\n"
58
  "1\n"
59
  "2\n"
60
  "3\n"
61
  "4\n"
62
  "@edges\n"
63
  "     label\n"
64
  "0 1  0\n"
65
  "0 2  0\n"
66
  "0 3  0\n"
67
  "0 4  0\n"
68
  "1 2  0\n"
69
  "1 3  0\n"
70
  "2 3  0\n"
71
  "2 4  0\n"
72
  "3 4  0\n",
73

	
74
  "@nodes\n"
75
  "label\n"
76
  "0\n"
77
  "1\n"
78
  "2\n"
79
  "3\n"
80
  "4\n"
81
  "5\n"
82
  "@edges\n"
83
  "     label\n"
84
  "0 3  0\n"
85
  "0 4  0\n"
86
  "0 5  0\n"
87
  "1 3  0\n"
88
  "1 4  0\n"
89
  "1 5  0\n"
90
  "2 3  0\n"
91
  "2 4  0\n"
92
  "2 5  0\n",
93

	
94
  "@nodes\n"
95
  "label\n"
96
  "0\n"
97
  "1\n"
98
  "2\n"
99
  "3\n"
100
  "4\n"
101
  "5\n"
102
  "@edges\n"
103
  "     label\n"
104
  "0 3  0\n"
105
  "0 4  0\n"
106
  "0 5  0\n"
107
  "1 3  0\n"
108
  "1 4  0\n"
109
  "1 5  0\n"
110
  "2 3  0\n"
111
  "2 5  0\n"
112
};
113

	
114

	
115

	
116
typedef SmartGraph Graph;
117
GRAPH_TYPEDEFS(Graph);
118

	
119
typedef PlanarEmbedding<SmartGraph> PE;
120
typedef PlanarDrawing<SmartGraph> PD;
121
typedef PlanarColoring<SmartGraph> PC;
122

	
123
void checkEmbedding(const Graph& graph, PE& pe) {
124
  int face_num = 0;
125

	
126
  Graph::ArcMap<int> face(graph, -1);
127

	
128
  for (ArcIt a(graph); a != INVALID; ++a) {
129
    if (face[a] == -1) {
130
      Arc b = a;
131
      while (face[b] == -1) {
132
        face[b] = face_num;
133
        b = pe.next(graph.oppositeArc(b));
134
      }
135
      check(face[b] == face_num, "Wrong face");
136
      ++face_num;
137
    }
138
  }
139
  check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
140
        countEdges(graph) + 1, "Euler test does not passed");
141
}
142

	
143
void checkKuratowski(const Graph& graph, PE& pe) {
144
  std::map<int, int> degs;
145
  for (NodeIt n(graph); n != INVALID; ++n) {
146
    int deg = 0;
147
    for (IncEdgeIt e(graph, n); e != INVALID; ++e) {
148
      if (pe.kuratowski(e)) {
149
        ++deg;
150
      }
151
    }
152
    ++degs[deg];
153
  }
154
  for (std::map<int, int>::iterator it = degs.begin(); it != degs.end(); ++it) {
155
    check(it->first == 0 || it->first == 2 ||
156
          (it->first == 3 && it->second == 6) ||
157
          (it->first == 4 && it->second == 5),
158
          "Wrong degree in Kuratowski graph");
159
  }
160

	
161
  // Not full test
162
  check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph");
163
}
164

	
165
bool intersect(Point<int> e1, Point<int> e2, Point<int> f1, Point<int> f2) {
166
  int l, r;
167
  if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false;
168
  if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false;
169
  if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false;
170
  if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false;
171

	
172
  l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x);
173
  r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x);
174
  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
175
  l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x);
176
  r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x);
177
  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
178
  return true;
179
}
180

	
181
bool collinear(Point<int> p, Point<int> q, Point<int> r) {
182
  int v;
183
  v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
184
  if (v != 0) return false;
185
  v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y);
186
  if (v < 0) return false;
187
  return true;
188
}
189

	
190
void checkDrawing(const Graph& graph, PD& pd) {
191
  for (Graph::NodeIt n(graph); n != INVALID; ++n) {
192
    Graph::NodeIt m(n);
193
    for (++m; m != INVALID; ++m) {
194
      check(pd[m] != pd[n], "Two nodes with identical coordinates");
195
    }
196
  }
197

	
198
  for (Graph::EdgeIt e(graph); e != INVALID; ++e) {
199
    for (Graph::EdgeIt f(e); f != e; ++f) {
200
      Point<int> e1 = pd[graph.u(e)];
201
      Point<int> e2 = pd[graph.v(e)];
202
      Point<int> f1 = pd[graph.u(f)];
203
      Point<int> f2 = pd[graph.v(f)];
204

	
205
      if (graph.u(e) == graph.u(f)) {
206
        check(!collinear(e1, e2, f2), "Wrong drawing");
207
      } else if (graph.u(e) == graph.v(f)) {
208
        check(!collinear(e1, e2, f1), "Wrong drawing");
209
      } else if (graph.v(e) == graph.u(f)) {
210
        check(!collinear(e2, e1, f2), "Wrong drawing");
211
      } else if (graph.v(e) == graph.v(f)) {
212
        check(!collinear(e2, e1, f1), "Wrong drawing");
213
      } else {
214
        check(!intersect(e1, e2, f1, f2), "Wrong drawing");
215
      }
216
    }
217
  }
218
}
219

	
220
void checkColoring(const Graph& graph, PC& pc, int num) {
221
  for (NodeIt n(graph); n != INVALID; ++n) {
222
    check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
223
          "Wrong coloring");
224
  }
225
  for (EdgeIt e(graph); e != INVALID; ++e) {
226
    check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
227
          "Wrong coloring");
228
  }
229
}
230

	
231
int main() {
232

	
233
  for (int i = 0; i < lgfn; ++i) {
234
    std::istringstream lgfs(lgf[i]);
235

	
236
    SmartGraph graph;
237
    graphReader(graph, lgfs).run();
238

	
239
    check(simpleGraph(graph), "Test graphs must be simple");
240

	
241
    PE pe(graph);
242
    bool planar = pe.run();
243
    check(checkPlanarity(graph) == planar, "Planarity checking failed");
244

	
245
    if (planar) {
246
      checkEmbedding(graph, pe);
247

	
248
      PlanarDrawing<Graph> pd(graph);
249
      pd.run(pe.embeddingMap());
250
      checkDrawing(graph, pd);
251

	
252
      PlanarColoring<Graph> pc(graph);
253
      pc.runFiveColoring(pe.embeddingMap());
254
      checkColoring(graph, pc, 5);
255

	
256
    } else {
257
      checkKuratowski(graph, pe);
258
    }
259
  }
260

	
261
  return 0;
262
}
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3 3
	lemon/CMakeLists.txt \
4 4
	lemon/config.h.cmake
5 5

	
6 6
pkgconfig_DATA += lemon/lemon.pc
7 7

	
8 8
lib_LTLIBRARIES += lemon/libemon.la
9 9

	
10 10
lemon_libemon_la_SOURCES = \
11 11
	lemon/arg_parser.cc \
12 12
	lemon/base.cc \
13 13
	lemon/color.cc \
14 14
	lemon/lp_base.cc \
15 15
	lemon/lp_skeleton.cc \
16 16
	lemon/random.cc \
17 17
	lemon/bits/windows.cc
18 18

	
19 19
nodist_lemon_HEADERS = lemon/config.h	
20 20

	
21 21
lemon_libemon_la_CXXFLAGS = \
22 22
	$(AM_CXXFLAGS) \
23 23
	$(GLPK_CFLAGS) \
24 24
	$(CPLEX_CFLAGS) \
25 25
	$(SOPLEX_CXXFLAGS) \
26 26
	$(CLP_CXXFLAGS) \
27 27
	$(CBC_CXXFLAGS)
28 28

	
29 29
lemon_libemon_la_LDFLAGS = \
30 30
	$(GLPK_LIBS) \
31 31
	$(CPLEX_LIBS) \
32 32
	$(SOPLEX_LIBS) \
33 33
	$(CLP_LIBS) \
34 34
	$(CBC_LIBS)
35 35

	
36 36
if HAVE_GLPK
37 37
lemon_libemon_la_SOURCES += lemon/glpk.cc
38 38
endif
39 39

	
40 40
if HAVE_CPLEX
41 41
lemon_libemon_la_SOURCES += lemon/cplex.cc
42 42
endif
43 43

	
44 44
if HAVE_SOPLEX
45 45
lemon_libemon_la_SOURCES += lemon/soplex.cc
46 46
endif
47 47

	
48 48
if HAVE_CLP
49 49
lemon_libemon_la_SOURCES += lemon/clp.cc
50 50
endif
51 51

	
52 52
if HAVE_CBC
53 53
lemon_libemon_la_SOURCES += lemon/cbc.cc
54 54
endif
55 55

	
56 56
lemon_HEADERS += \
57 57
	lemon/adaptors.h \
58 58
	lemon/arg_parser.h \
59 59
	lemon/assert.h \
60 60
	lemon/bellman_ford.h \
61 61
	lemon/bfs.h \
62 62
	lemon/bin_heap.h \
63 63
	lemon/binom_heap.h \
64 64
	lemon/bucket_heap.h \
65 65
	lemon/capacity_scaling.h \
66 66
	lemon/cbc.h \
67 67
	lemon/circulation.h \
68 68
	lemon/clp.h \
69 69
	lemon/color.h \
70 70
	lemon/concept_check.h \
71 71
	lemon/connectivity.h \
72 72
	lemon/core.h \
73 73
	lemon/cost_scaling.h \
74 74
	lemon/counter.h \
75 75
	lemon/cplex.h \
76 76
	lemon/cycle_canceling.h \
77 77
	lemon/dfs.h \
78 78
	lemon/dijkstra.h \
79 79
	lemon/dim2.h \
80 80
	lemon/dimacs.h \
81 81
	lemon/edge_set.h \
82 82
	lemon/elevator.h \
83 83
	lemon/error.h \
84 84
	lemon/euler.h \
85 85
	lemon/fib_heap.h \
86 86
	lemon/fourary_heap.h \
87 87
	lemon/full_graph.h \
88 88
	lemon/glpk.h \
89 89
	lemon/gomory_hu.h \
90 90
	lemon/graph_to_eps.h \
91 91
	lemon/grid_graph.h \
92 92
	lemon/hartmann_orlin.h \
93 93
	lemon/howard.h \
94 94
	lemon/hypercube_graph.h \
95 95
	lemon/karp.h \
96 96
	lemon/kary_heap.h \
97 97
	lemon/kruskal.h \
98 98
	lemon/hao_orlin.h \
99 99
	lemon/lgf_reader.h \
100 100
	lemon/lgf_writer.h \
101 101
	lemon/list_graph.h \
102 102
	lemon/lp.h \
103 103
	lemon/lp_base.h \
104 104
	lemon/lp_skeleton.h \
105 105
	lemon/maps.h \
106 106
	lemon/matching.h \
107 107
	lemon/math.h \
108 108
	lemon/min_cost_arborescence.h \
109 109
	lemon/nauty_reader.h \
110 110
	lemon/network_simplex.h \
111 111
	lemon/pairing_heap.h \
112 112
	lemon/path.h \
113
	lemon/planarity.h \
113 114
	lemon/preflow.h \
114 115
	lemon/radix_heap.h \
115 116
	lemon/radix_sort.h \
116 117
	lemon/random.h \
117 118
	lemon/smart_graph.h \
118 119
	lemon/soplex.h \
119 120
	lemon/static_graph.h \
120 121
	lemon/suurballe.h \
121 122
	lemon/time_measure.h \
122 123
	lemon/tolerance.h \
123 124
	lemon/unionfind.h \
124 125
	lemon/bits/windows.h
125 126

	
126 127
bits_HEADERS += \
127 128
	lemon/bits/alteration_notifier.h \
128 129
	lemon/bits/array_map.h \
129 130
	lemon/bits/bezier.h \
130 131
	lemon/bits/default_map.h \
131 132
	lemon/bits/edge_set_extender.h \
132 133
	lemon/bits/enable_if.h \
133 134
	lemon/bits/graph_adaptor_extender.h \
134 135
	lemon/bits/graph_extender.h \
135 136
	lemon/bits/map_extender.h \
136 137
	lemon/bits/path_dump.h \
137 138
	lemon/bits/solver_bits.h \
138 139
	lemon/bits/traits.h \
139 140
	lemon/bits/variant.h \
140 141
	lemon/bits/vector_map.h
141 142

	
142 143
concept_HEADERS += \
143 144
	lemon/concepts/digraph.h \
144 145
	lemon/concepts/graph.h \
145 146
	lemon/concepts/graph_components.h \
146 147
	lemon/concepts/heap.h \
147 148
	lemon/concepts/maps.h \
148 149
	lemon/concepts/path.h
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BITS_MAP_EXTENDER_H
20 20
#define LEMON_BITS_MAP_EXTENDER_H
21 21

	
22 22
#include <iterator>
23 23

	
24 24
#include <lemon/bits/traits.h>
25 25

	
26 26
#include <lemon/concept_check.h>
27 27
#include <lemon/concepts/maps.h>
28 28

	
29 29
//\file
30 30
//\brief Extenders for iterable maps.
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  // \ingroup graphbits
35 35
  //
36 36
  // \brief Extender for maps
37 37
  template <typename _Map>
38 38
  class MapExtender : public _Map {
39 39
    typedef _Map Parent;
40 40
    typedef typename Parent::GraphType GraphType;
41 41

	
42 42
  public:
43 43

	
44 44
    typedef MapExtender Map;
45 45
    typedef typename Parent::Key Item;
46 46

	
47 47
    typedef typename Parent::Key Key;
48 48
    typedef typename Parent::Value Value;
49 49
    typedef typename Parent::Reference Reference;
50 50
    typedef typename Parent::ConstReference ConstReference;
51 51

	
52 52
    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
53 53

	
54 54
    class MapIt;
55 55
    class ConstMapIt;
56 56

	
57 57
    friend class MapIt;
58 58
    friend class ConstMapIt;
59 59

	
60 60
  public:
61 61

	
62 62
    MapExtender(const GraphType& graph)
63 63
      : Parent(graph) {}
64 64

	
65 65
    MapExtender(const GraphType& graph, const Value& value)
66 66
      : Parent(graph, value) {}
67 67

	
68 68
  private:
69 69
    MapExtender& operator=(const MapExtender& cmap) {
70 70
      return operator=<MapExtender>(cmap);
71 71
    }
72 72

	
73 73
    template <typename CMap>
74 74
    MapExtender& operator=(const CMap& cmap) {
75 75
      Parent::operator=(cmap);
76 76
      return *this;
77 77
    }
78 78

	
79 79
  public:
80 80
    class MapIt : public Item {
81 81
      typedef Item Parent;
82 82

	
83 83
    public:
84 84

	
85 85
      typedef typename Map::Value Value;
86 86

	
87
      MapIt() {}
87
      MapIt() : map(NULL) {}
88 88

	
89
      MapIt(Invalid i) : Parent(i) { }
89
      MapIt(Invalid i) : Parent(i), map(NULL) {}
90 90

	
91
      explicit MapIt(Map& _map) : map(_map) {
92
        map.notifier()->first(*this);
91
      explicit MapIt(Map& _map) : map(&_map) {
92
        map->notifier()->first(*this);
93 93
      }
94 94

	
95 95
      MapIt(const Map& _map, const Item& item)
96
        : Parent(item), map(_map) {}
96
        : Parent(item), map(&_map) {}
97 97

	
98 98
      MapIt& operator++() {
99
        map.notifier()->next(*this);
99
        map->notifier()->next(*this);
100 100
        return *this;
101 101
      }
102 102

	
103 103
      typename MapTraits<Map>::ConstReturnValue operator*() const {
104
        return map[*this];
104
        return (*map)[*this];
105 105
      }
106 106

	
107 107
      typename MapTraits<Map>::ReturnValue operator*() {
108
        return map[*this];
108
        return (*map)[*this];
109 109
      }
110 110

	
111 111
      void set(const Value& value) {
112
        map.set(*this, value);
112
        map->set(*this, value);
113 113
      }
114 114

	
115 115
    protected:
116
      Map& map;
116
      Map* map;
117 117

	
118 118
    };
119 119

	
120 120
    class ConstMapIt : public Item {
121 121
      typedef Item Parent;
122 122

	
123 123
    public:
124 124

	
125 125
      typedef typename Map::Value Value;
126 126

	
127
      ConstMapIt() {}
127
      ConstMapIt() : map(NULL) {}
128 128

	
129
      ConstMapIt(Invalid i) : Parent(i) { }
129
      ConstMapIt(Invalid i) : Parent(i), map(NULL) {}
130 130

	
131
      explicit ConstMapIt(Map& _map) : map(_map) {
132
        map.notifier()->first(*this);
131
      explicit ConstMapIt(Map& _map) : map(&_map) {
132
        map->notifier()->first(*this);
133 133
      }
134 134

	
135 135
      ConstMapIt(const Map& _map, const Item& item)
136 136
        : Parent(item), map(_map) {}
137 137

	
138 138
      ConstMapIt& operator++() {
139
        map.notifier()->next(*this);
139
        map->notifier()->next(*this);
140 140
        return *this;
141 141
      }
142 142

	
143 143
      typename MapTraits<Map>::ConstReturnValue operator*() const {
144 144
        return map[*this];
145 145
      }
146 146

	
147 147
    protected:
148
      const Map& map;
148
      const Map* map;
149 149
    };
150 150

	
151 151
    class ItemIt : public Item {
152 152
      typedef Item Parent;
153 153

	
154 154
    public:
155
      ItemIt() : map(NULL) {}
155 156

	
156
      ItemIt() {}
157 157

	
158
      ItemIt(Invalid i) : Parent(i) { }
158
      ItemIt(Invalid i) : Parent(i), map(NULL) {}
159 159

	
160
      explicit ItemIt(Map& _map) : map(_map) {
161
        map.notifier()->first(*this);
160
      explicit ItemIt(Map& _map) : map(&_map) {
161
        map->notifier()->first(*this);
162 162
      }
163 163

	
164 164
      ItemIt(const Map& _map, const Item& item)
165
        : Parent(item), map(_map) {}
165
        : Parent(item), map(&_map) {}
166 166

	
167 167
      ItemIt& operator++() {
168
        map.notifier()->next(*this);
168
        map->notifier()->next(*this);
169 169
        return *this;
170 170
      }
171 171

	
172 172
    protected:
173
      const Map& map;
173
      const Map* map;
174 174

	
175 175
    };
176 176
  };
177 177

	
178 178
  // \ingroup graphbits
179 179
  //
180 180
  // \brief Extender for maps which use a subset of the items.
181 181
  template <typename _Graph, typename _Map>
182 182
  class SubMapExtender : public _Map {
183 183
    typedef _Map Parent;
184 184
    typedef _Graph GraphType;
185 185

	
186 186
  public:
187 187

	
188 188
    typedef SubMapExtender Map;
189 189
    typedef typename Parent::Key Item;
190 190

	
191 191
    typedef typename Parent::Key Key;
192 192
    typedef typename Parent::Value Value;
193 193
    typedef typename Parent::Reference Reference;
194 194
    typedef typename Parent::ConstReference ConstReference;
195 195

	
196 196
    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
197 197

	
198 198
    class MapIt;
199 199
    class ConstMapIt;
200 200

	
201 201
    friend class MapIt;
202 202
    friend class ConstMapIt;
203 203

	
204 204
  public:
205 205

	
206 206
    SubMapExtender(const GraphType& _graph)
207 207
      : Parent(_graph), graph(_graph) {}
208 208

	
209 209
    SubMapExtender(const GraphType& _graph, const Value& _value)
210 210
      : Parent(_graph, _value), graph(_graph) {}
211 211

	
212 212
  private:
213 213
    SubMapExtender& operator=(const SubMapExtender& cmap) {
214 214
      return operator=<MapExtender>(cmap);
215 215
    }
216 216

	
217 217
    template <typename CMap>
218 218
    SubMapExtender& operator=(const CMap& cmap) {
219 219
      checkConcept<concepts::ReadMap<Key, Value>, CMap>();
220 220
      Item it;
221 221
      for (graph.first(it); it != INVALID; graph.next(it)) {
222 222
        Parent::set(it, cmap[it]);
223 223
      }
224 224
      return *this;
225 225
    }
226 226

	
227 227
  public:
228 228
    class MapIt : public Item {
229 229
      typedef Item Parent;
230 230

	
231 231
    public:
232 232
      typedef typename Map::Value Value;
233 233

	
234
      MapIt() {}
234
      MapIt() : map(NULL) {}
235 235

	
236
      MapIt(Invalid i) : Parent(i) { }
236
      MapIt(Invalid i) : Parent(i), map(NULL) { }
237 237

	
238
      explicit MapIt(Map& _map) : map(_map) {
239
        map.graph.first(*this);
238
      explicit MapIt(Map& _map) : map(&_map) {
239
        map->graph.first(*this);
240 240
      }
241 241

	
242 242
      MapIt(const Map& _map, const Item& item)
243
        : Parent(item), map(_map) {}
243
        : Parent(item), map(&_map) {}
244 244

	
245 245
      MapIt& operator++() {
246
        map.graph.next(*this);
246
        map->graph.next(*this);
247 247
        return *this;
248 248
      }
249 249

	
250 250
      typename MapTraits<Map>::ConstReturnValue operator*() const {
251
        return map[*this];
251
        return (*map)[*this];
252 252
      }
253 253

	
254 254
      typename MapTraits<Map>::ReturnValue operator*() {
255
        return map[*this];
255
        return (*map)[*this];
256 256
      }
257 257

	
258 258
      void set(const Value& value) {
259
        map.set(*this, value);
259
        map->set(*this, value);
260 260
      }
261 261

	
262 262
    protected:
263
      Map& map;
263
      Map* map;
264 264

	
265 265
    };
266 266

	
267 267
    class ConstMapIt : public Item {
268 268
      typedef Item Parent;
269 269

	
270 270
    public:
271 271

	
272 272
      typedef typename Map::Value Value;
273 273

	
274
      ConstMapIt() {}
274
      ConstMapIt() : map(NULL) {}
275 275

	
276
      ConstMapIt(Invalid i) : Parent(i) { }
276
      ConstMapIt(Invalid i) : Parent(i), map(NULL) { }
277 277

	
278
      explicit ConstMapIt(Map& _map) : map(_map) {
279
        map.graph.first(*this);
278
      explicit ConstMapIt(Map& _map) : map(&_map) {
279
        map->graph.first(*this);
280 280
      }
281 281

	
282 282
      ConstMapIt(const Map& _map, const Item& item)
283
        : Parent(item), map(_map) {}
283
        : Parent(item), map(&_map) {}
284 284

	
285 285
      ConstMapIt& operator++() {
286
        map.graph.next(*this);
286
        map->graph.next(*this);
287 287
        return *this;
288 288
      }
289 289

	
290 290
      typename MapTraits<Map>::ConstReturnValue operator*() const {
291
        return map[*this];
291
        return (*map)[*this];
292 292
      }
293 293

	
294 294
    protected:
295
      const Map& map;
295
      const Map* map;
296 296
    };
297 297

	
298 298
    class ItemIt : public Item {
299 299
      typedef Item Parent;
300 300

	
301 301
    public:
302
      ItemIt() : map(NULL) {}
302 303

	
303
      ItemIt() {}
304 304

	
305
      ItemIt(Invalid i) : Parent(i) { }
305
      ItemIt(Invalid i) : Parent(i), map(NULL) { }
306 306

	
307
      explicit ItemIt(Map& _map) : map(_map) {
308
        map.graph.first(*this);
307
      explicit ItemIt(Map& _map) : map(&_map) {
308
        map->graph.first(*this);
309 309
      }
310 310

	
311 311
      ItemIt(const Map& _map, const Item& item)
312
        : Parent(item), map(_map) {}
312
        : Parent(item), map(&_map) {}
313 313

	
314 314
      ItemIt& operator++() {
315
        map.graph.next(*this);
315
        map->graph.next(*this);
316 316
        return *this;
317 317
      }
318 318

	
319 319
    protected:
320
      const Map& map;
320
      const Map* map;
321 321

	
322 322
    };
323 323

	
324 324
  private:
325 325

	
326 326
    const GraphType& graph;
327 327

	
328 328
  };
329 329

	
330 330
}
331 331

	
332 332
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_UNION_FIND_H
20 20
#define LEMON_UNION_FIND_H
21 21

	
22 22
//!\ingroup auxdat
23 23
//!\file
24 24
//!\brief Union-Find data structures.
25 25
//!
26 26

	
27 27
#include <vector>
28 28
#include <list>
29 29
#include <utility>
30 30
#include <algorithm>
31 31
#include <functional>
32 32

	
33 33
#include <lemon/core.h>
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  /// \ingroup auxdat
38 38
  ///
39 39
  /// \brief A \e Union-Find data structure implementation
40 40
  ///
41 41
  /// The class implements the \e Union-Find data structure.
42 42
  /// The union operation uses rank heuristic, while
43 43
  /// the find operation uses path compression.
44 44
  /// This is a very simple but efficient implementation, providing
45 45
  /// only four methods: join (union), find, insert and size.
46 46
  /// For more features, see the \ref UnionFindEnum class.
47 47
  ///
48 48
  /// It is primarily used in Kruskal algorithm for finding minimal
49 49
  /// cost spanning tree in a graph.
50 50
  /// \sa kruskal()
51 51
  ///
52 52
  /// \pre You need to add all the elements by the \ref insert()
53 53
  /// method.
54 54
  template <typename IM>
55 55
  class UnionFind {
56 56
  public:
57 57

	
58 58
    ///\e
59 59
    typedef IM ItemIntMap;
60 60
    ///\e
61 61
    typedef typename ItemIntMap::Key Item;
62 62

	
63 63
  private:
64 64
    // If the items vector stores negative value for an item then
65 65
    // that item is root item and it has -items[it] component size.
66 66
    // Else the items[it] contains the index of the parent.
67 67
    std::vector<int> items;
68 68
    ItemIntMap& index;
69 69

	
70 70
    bool rep(int idx) const {
71 71
      return items[idx] < 0;
72 72
    }
73 73

	
74 74
    int repIndex(int idx) const {
75 75
      int k = idx;
76 76
      while (!rep(k)) {
77 77
        k = items[k] ;
78 78
      }
79 79
      while (idx != k) {
80 80
        int next = items[idx];
81 81
        const_cast<int&>(items[idx]) = k;
82 82
        idx = next;
83 83
      }
84 84
      return k;
85 85
    }
86 86

	
87 87
  public:
88 88

	
89 89
    /// \brief Constructor
90 90
    ///
91 91
    /// Constructor of the UnionFind class. You should give an item to
92 92
    /// integer map which will be used from the data structure. If you
93 93
    /// modify directly this map that may cause segmentation fault,
94 94
    /// invalid data structure, or infinite loop when you use again
95 95
    /// the union-find.
96 96
    UnionFind(ItemIntMap& m) : index(m) {}
97 97

	
98 98
    /// \brief Returns the index of the element's component.
99 99
    ///
100 100
    /// The method returns the index of the element's component.
101 101
    /// This is an integer between zero and the number of inserted elements.
102 102
    ///
103 103
    int find(const Item& a) {
104 104
      return repIndex(index[a]);
105 105
    }
106 106

	
107 107
    /// \brief Clears the union-find data structure
108 108
    ///
109 109
    /// Erase each item from the data structure.
110 110
    void clear() {
111 111
      items.clear();
112 112
    }
113 113

	
114 114
    /// \brief Inserts a new element into the structure.
115 115
    ///
116 116
    /// This method inserts a new element into the data structure.
117 117
    ///
118 118
    /// The method returns the index of the new component.
119 119
    int insert(const Item& a) {
120 120
      int n = items.size();
121 121
      items.push_back(-1);
122 122
      index.set(a,n);
123 123
      return n;
124 124
    }
125 125

	
126 126
    /// \brief Joining the components of element \e a and element \e b.
127 127
    ///
128 128
    /// This is the \e union operation of the Union-Find structure.
129 129
    /// Joins the component of element \e a and component of
130 130
    /// element \e b. If \e a and \e b are in the same component then
131 131
    /// it returns false otherwise it returns true.
132 132
    bool join(const Item& a, const Item& b) {
133 133
      int ka = repIndex(index[a]);
134 134
      int kb = repIndex(index[b]);
135 135

	
136 136
      if ( ka == kb )
137 137
        return false;
138 138

	
139 139
      if (items[ka] < items[kb]) {
140 140
        items[ka] += items[kb];
141 141
        items[kb] = ka;
142 142
      } else {
143 143
        items[kb] += items[ka];
144 144
        items[ka] = kb;
145 145
      }
146 146
      return true;
147 147
    }
148 148

	
149 149
    /// \brief Returns the size of the component of element \e a.
150 150
    ///
151 151
    /// Returns the size of the component of element \e a.
152 152
    int size(const Item& a) {
153 153
      int k = repIndex(index[a]);
154 154
      return - items[k];
155 155
    }
156 156

	
157 157
  };
158 158

	
159 159
  /// \ingroup auxdat
160 160
  ///
161 161
  /// \brief A \e Union-Find data structure implementation which
162 162
  /// is able to enumerate the components.
163 163
  ///
164 164
  /// The class implements a \e Union-Find data structure
165 165
  /// which is able to enumerate the components and the items in
166 166
  /// a component. If you don't need this feature then perhaps it's
167 167
  /// better to use the \ref UnionFind class which is more efficient.
168 168
  ///
169 169
  /// The union operation uses rank heuristic, while
170 170
  /// the find operation uses path compression.
171 171
  ///
172 172
  /// \pre You need to add all the elements by the \ref insert()
173 173
  /// method.
174 174
  ///
175 175
  template <typename IM>
176 176
  class UnionFindEnum {
177 177
  public:
178 178

	
179 179
    ///\e
180 180
    typedef IM ItemIntMap;
181 181
    ///\e
182 182
    typedef typename ItemIntMap::Key Item;
183 183

	
184 184
  private:
185 185

	
186 186
    ItemIntMap& index;
187 187

	
188 188
    // If the parent stores negative value for an item then that item
189 189
    // is root item and it has ~(items[it].parent) component id.  Else
190 190
    // the items[it].parent contains the index of the parent.
191 191
    //
192 192
    // The \c next and \c prev provides the double-linked
193 193
    // cyclic list of one component's items.
194 194
    struct ItemT {
195 195
      int parent;
196 196
      Item item;
197 197

	
198 198
      int next, prev;
199 199
    };
200 200

	
201 201
    std::vector<ItemT> items;
202 202
    int firstFreeItem;
203 203

	
204 204
    struct ClassT {
205 205
      int size;
206 206
      int firstItem;
207 207
      int next, prev;
208 208
    };
209 209

	
210 210
    std::vector<ClassT> classes;
211 211
    int firstClass, firstFreeClass;
212 212

	
213 213
    int newClass() {
214 214
      if (firstFreeClass == -1) {
215 215
        int cdx = classes.size();
216 216
        classes.push_back(ClassT());
217 217
        return cdx;
218 218
      } else {
219 219
        int cdx = firstFreeClass;
220 220
        firstFreeClass = classes[firstFreeClass].next;
221 221
        return cdx;
222 222
      }
223 223
    }
224 224

	
225 225
    int newItem() {
226 226
      if (firstFreeItem == -1) {
227 227
        int idx = items.size();
228 228
        items.push_back(ItemT());
229 229
        return idx;
230 230
      } else {
231 231
        int idx = firstFreeItem;
232 232
        firstFreeItem = items[firstFreeItem].next;
233 233
        return idx;
234 234
      }
235 235
    }
236 236

	
237 237

	
238 238
    bool rep(int idx) const {
239 239
      return items[idx].parent < 0;
240 240
    }
241 241

	
242 242
    int repIndex(int idx) const {
243 243
      int k = idx;
244 244
      while (!rep(k)) {
245 245
        k = items[k].parent;
246 246
      }
247 247
      while (idx != k) {
248 248
        int next = items[idx].parent;
249 249
        const_cast<int&>(items[idx].parent) = k;
250 250
        idx = next;
251 251
      }
252 252
      return k;
253 253
    }
254 254

	
255 255
    int classIndex(int idx) const {
256 256
      return ~(items[repIndex(idx)].parent);
257 257
    }
258 258

	
259 259
    void singletonItem(int idx) {
260 260
      items[idx].next = idx;
261 261
      items[idx].prev = idx;
262 262
    }
263 263

	
264 264
    void laceItem(int idx, int rdx) {
265 265
      items[idx].prev = rdx;
266 266
      items[idx].next = items[rdx].next;
267 267
      items[items[rdx].next].prev = idx;
268 268
      items[rdx].next = idx;
269 269
    }
270 270

	
271 271
    void unlaceItem(int idx) {
272 272
      items[items[idx].prev].next = items[idx].next;
273 273
      items[items[idx].next].prev = items[idx].prev;
274 274

	
275 275
      items[idx].next = firstFreeItem;
276 276
      firstFreeItem = idx;
277 277
    }
278 278

	
279 279
    void spliceItems(int ak, int bk) {
280 280
      items[items[ak].prev].next = bk;
281 281
      items[items[bk].prev].next = ak;
282 282
      int tmp = items[ak].prev;
283 283
      items[ak].prev = items[bk].prev;
284 284
      items[bk].prev = tmp;
285 285

	
286 286
    }
287 287

	
288 288
    void laceClass(int cls) {
289 289
      if (firstClass != -1) {
290 290
        classes[firstClass].prev = cls;
291 291
      }
292 292
      classes[cls].next = firstClass;
293 293
      classes[cls].prev = -1;
294 294
      firstClass = cls;
295 295
    }
296 296

	
297 297
    void unlaceClass(int cls) {
298 298
      if (classes[cls].prev != -1) {
299 299
        classes[classes[cls].prev].next = classes[cls].next;
300 300
      } else {
301 301
        firstClass = classes[cls].next;
302 302
      }
303 303
      if (classes[cls].next != -1) {
304 304
        classes[classes[cls].next].prev = classes[cls].prev;
305 305
      }
306 306

	
307 307
      classes[cls].next = firstFreeClass;
308 308
      firstFreeClass = cls;
309 309
    }
310 310

	
311 311
  public:
312 312

	
313 313
    UnionFindEnum(ItemIntMap& _index)
314 314
      : index(_index), items(), firstFreeItem(-1),
315 315
        firstClass(-1), firstFreeClass(-1) {}
316 316

	
317 317
    /// \brief Inserts the given element into a new component.
318 318
    ///
319 319
    /// This method creates a new component consisting only of the
320 320
    /// given element.
321 321
    ///
322 322
    int insert(const Item& item) {
323 323
      int idx = newItem();
324 324

	
325 325
      index.set(item, idx);
326 326

	
327 327
      singletonItem(idx);
328 328
      items[idx].item = item;
329 329

	
330 330
      int cdx = newClass();
331 331

	
332 332
      items[idx].parent = ~cdx;
333 333

	
334 334
      laceClass(cdx);
335 335
      classes[cdx].size = 1;
336 336
      classes[cdx].firstItem = idx;
337 337

	
338 338
      firstClass = cdx;
339 339

	
340 340
      return cdx;
341 341
    }
342 342

	
343 343
    /// \brief Inserts the given element into the component of the others.
344 344
    ///
345 345
    /// This methods inserts the element \e a into the component of the
346 346
    /// element \e comp.
347 347
    void insert(const Item& item, int cls) {
348 348
      int rdx = classes[cls].firstItem;
349 349
      int idx = newItem();
350 350

	
351 351
      index.set(item, idx);
352 352

	
353 353
      laceItem(idx, rdx);
354 354

	
355 355
      items[idx].item = item;
356 356
      items[idx].parent = rdx;
357 357

	
358 358
      ++classes[~(items[rdx].parent)].size;
359 359
    }
360 360

	
361 361
    /// \brief Clears the union-find data structure
362 362
    ///
363 363
    /// Erase each item from the data structure.
364 364
    void clear() {
365 365
      items.clear();
366 366
      firstClass = -1;
367 367
      firstFreeItem = -1;
368 368
    }
369 369

	
370 370
    /// \brief Finds the component of the given element.
371 371
    ///
372 372
    /// The method returns the component id of the given element.
373 373
    int find(const Item &item) const {
374 374
      return ~(items[repIndex(index[item])].parent);
375 375
    }
376 376

	
377 377
    /// \brief Joining the component of element \e a and element \e b.
378 378
    ///
379 379
    /// This is the \e union operation of the Union-Find structure.
380 380
    /// Joins the component of element \e a and component of
381 381
    /// element \e b. If \e a and \e b are in the same component then
382 382
    /// returns -1 else returns the remaining class.
383 383
    int join(const Item& a, const Item& b) {
384 384

	
385 385
      int ak = repIndex(index[a]);
386 386
      int bk = repIndex(index[b]);
387 387

	
388 388
      if (ak == bk) {
389 389
        return -1;
390 390
      }
391 391

	
392 392
      int acx = ~(items[ak].parent);
393 393
      int bcx = ~(items[bk].parent);
394 394

	
395 395
      int rcx;
396 396

	
397 397
      if (classes[acx].size > classes[bcx].size) {
398 398
        classes[acx].size += classes[bcx].size;
399 399
        items[bk].parent = ak;
400 400
        unlaceClass(bcx);
401 401
        rcx = acx;
402 402
      } else {
403 403
        classes[bcx].size += classes[acx].size;
404 404
        items[ak].parent = bk;
405 405
        unlaceClass(acx);
406 406
        rcx = bcx;
407 407
      }
408 408
      spliceItems(ak, bk);
409 409

	
410 410
      return rcx;
411 411
    }
412 412

	
413 413
    /// \brief Returns the size of the class.
414 414
    ///
415 415
    /// Returns the size of the class.
416 416
    int size(int cls) const {
417 417
      return classes[cls].size;
418 418
    }
419 419

	
420 420
    /// \brief Splits up the component.
421 421
    ///
422 422
    /// Splitting the component into singleton components (component
423 423
    /// of size one).
424 424
    void split(int cls) {
425 425
      int fdx = classes[cls].firstItem;
426 426
      int idx = items[fdx].next;
427 427
      while (idx != fdx) {
428 428
        int next = items[idx].next;
429 429

	
430 430
        singletonItem(idx);
431 431

	
432 432
        int cdx = newClass();
433 433
        items[idx].parent = ~cdx;
434 434

	
435 435
        laceClass(cdx);
436 436
        classes[cdx].size = 1;
437 437
        classes[cdx].firstItem = idx;
438 438

	
439 439
        idx = next;
440 440
      }
441 441

	
442 442
      items[idx].prev = idx;
443 443
      items[idx].next = idx;
444 444

	
445 445
      classes[~(items[idx].parent)].size = 1;
446 446

	
447 447
    }
448 448

	
449 449
    /// \brief Removes the given element from the structure.
450 450
    ///
451 451
    /// Removes the element from its component and if the component becomes
452 452
    /// empty then removes that component from the component list.
453 453
    ///
454 454
    /// \warning It is an error to remove an element which is not in
455 455
    /// the structure.
456 456
    /// \warning This running time of this operation is proportional to the
457 457
    /// number of the items in this class.
458 458
    void erase(const Item& item) {
459 459
      int idx = index[item];
460 460
      int fdx = items[idx].next;
461 461

	
462 462
      int cdx = classIndex(idx);
463 463
      if (idx == fdx) {
464 464
        unlaceClass(cdx);
465 465
        items[idx].next = firstFreeItem;
466 466
        firstFreeItem = idx;
467 467
        return;
468 468
      } else {
469 469
        classes[cdx].firstItem = fdx;
470 470
        --classes[cdx].size;
471 471
        items[fdx].parent = ~cdx;
472 472

	
473 473
        unlaceItem(idx);
474 474
        idx = items[fdx].next;
475 475
        while (idx != fdx) {
476 476
          items[idx].parent = fdx;
477 477
          idx = items[idx].next;
478 478
        }
479 479

	
480 480
      }
481 481

	
482 482
    }
483 483

	
484 484
    /// \brief Gives back a representant item of the component.
485 485
    ///
486 486
    /// Gives back a representant item of the component.
487 487
    Item item(int cls) const {
488 488
      return items[classes[cls].firstItem].item;
489 489
    }
490 490

	
491 491
    /// \brief Removes the component of the given element from the structure.
492 492
    ///
493 493
    /// Removes the component of the given element from the structure.
494 494
    ///
495 495
    /// \warning It is an error to give an element which is not in the
496 496
    /// structure.
497 497
    void eraseClass(int cls) {
498 498
      int fdx = classes[cls].firstItem;
499 499
      unlaceClass(cls);
500 500
      items[items[fdx].prev].next = firstFreeItem;
501 501
      firstFreeItem = fdx;
502 502
    }
503 503

	
504 504
    /// \brief LEMON style iterator for the representant items.
505 505
    ///
506 506
    /// ClassIt is a lemon style iterator for the components. It iterates
507 507
    /// on the ids of the classes.
508 508
    class ClassIt {
509 509
    public:
510 510
      /// \brief Constructor of the iterator
511 511
      ///
512 512
      /// Constructor of the iterator
513 513
      ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
514 514
        cdx = unionFind->firstClass;
515 515
      }
516 516

	
517 517
      /// \brief Constructor to get invalid iterator
518 518
      ///
519 519
      /// Constructor to get invalid iterator
520 520
      ClassIt(Invalid) : unionFind(0), cdx(-1) {}
521 521

	
522 522
      /// \brief Increment operator
523 523
      ///
524 524
      /// It steps to the next representant item.
525 525
      ClassIt& operator++() {
526 526
        cdx = unionFind->classes[cdx].next;
527 527
        return *this;
528 528
      }
529 529

	
530 530
      /// \brief Conversion operator
531 531
      ///
532 532
      /// It converts the iterator to the current representant item.
533 533
      operator int() const {
534 534
        return cdx;
535 535
      }
536 536

	
537 537
      /// \brief Equality operator
538 538
      ///
539 539
      /// Equality operator
540 540
      bool operator==(const ClassIt& i) {
541 541
        return i.cdx == cdx;
542 542
      }
543 543

	
544 544
      /// \brief Inequality operator
545 545
      ///
546 546
      /// Inequality operator
547 547
      bool operator!=(const ClassIt& i) {
548 548
        return i.cdx != cdx;
549 549
      }
550 550

	
551 551
    private:
552 552
      const UnionFindEnum* unionFind;
553 553
      int cdx;
554 554
    };
555 555

	
556 556
    /// \brief LEMON style iterator for the items of a component.
557 557
    ///
558 558
    /// ClassIt is a lemon style iterator for the components. It iterates
559 559
    /// on the items of a class. By example if you want to iterate on
560 560
    /// each items of each classes then you may write the next code.
561 561
    ///\code
562 562
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
563 563
    ///   std::cout << "Class: ";
564 564
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
565 565
    ///     std::cout << toString(iit) << ' ' << std::endl;
566 566
    ///   }
567 567
    ///   std::cout << std::endl;
568 568
    /// }
569 569
    ///\endcode
570 570
    class ItemIt {
571 571
    public:
572 572
      /// \brief Constructor of the iterator
573 573
      ///
574 574
      /// Constructor of the iterator. The iterator iterates
575 575
      /// on the class of the \c item.
576 576
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
577 577
        fdx = idx = unionFind->classes[cls].firstItem;
578 578
      }
579 579

	
580 580
      /// \brief Constructor to get invalid iterator
581 581
      ///
582 582
      /// Constructor to get invalid iterator
583 583
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
584 584

	
585 585
      /// \brief Increment operator
586 586
      ///
587 587
      /// It steps to the next item in the class.
588 588
      ItemIt& operator++() {
589 589
        idx = unionFind->items[idx].next;
590 590
        if (idx == fdx) idx = -1;
591 591
        return *this;
592 592
      }
593 593

	
594 594
      /// \brief Conversion operator
595 595
      ///
596 596
      /// It converts the iterator to the current item.
597 597
      operator const Item&() const {
598 598
        return unionFind->items[idx].item;
599 599
      }
600 600

	
601 601
      /// \brief Equality operator
602 602
      ///
603 603
      /// Equality operator
604 604
      bool operator==(const ItemIt& i) {
605 605
        return i.idx == idx;
606 606
      }
607 607

	
608 608
      /// \brief Inequality operator
609 609
      ///
610 610
      /// Inequality operator
611 611
      bool operator!=(const ItemIt& i) {
612 612
        return i.idx != idx;
613 613
      }
614 614

	
615 615
    private:
616 616
      const UnionFindEnum* unionFind;
617 617
      int idx, fdx;
618 618
    };
619 619

	
620 620
  };
621 621

	
622 622
  /// \ingroup auxdat
623 623
  ///
624 624
  /// \brief A \e Extend-Find data structure implementation which
625 625
  /// is able to enumerate the components.
626 626
  ///
627 627
  /// The class implements an \e Extend-Find data structure which is
628 628
  /// able to enumerate the components and the items in a
629 629
  /// component. The data structure is a simplification of the
630 630
  /// Union-Find structure, and it does not allow to merge two components.
631 631
  ///
632 632
  /// \pre You need to add all the elements by the \ref insert()
633 633
  /// method.
634 634
  template <typename IM>
635 635
  class ExtendFindEnum {
636 636
  public:
637 637

	
638 638
    ///\e
639 639
    typedef IM ItemIntMap;
640 640
    ///\e
641 641
    typedef typename ItemIntMap::Key Item;
642 642

	
643 643
  private:
644 644

	
645 645
    ItemIntMap& index;
646 646

	
647 647
    struct ItemT {
648 648
      int cls;
649 649
      Item item;
650 650
      int next, prev;
651 651
    };
652 652

	
653 653
    std::vector<ItemT> items;
654 654
    int firstFreeItem;
655 655

	
656 656
    struct ClassT {
657 657
      int firstItem;
658 658
      int next, prev;
659 659
    };
660 660

	
661 661
    std::vector<ClassT> classes;
662 662

	
663 663
    int firstClass, firstFreeClass;
664 664

	
665 665
    int newClass() {
666 666
      if (firstFreeClass != -1) {
667 667
        int cdx = firstFreeClass;
668 668
        firstFreeClass = classes[cdx].next;
669 669
        return cdx;
670 670
      } else {
671 671
        classes.push_back(ClassT());
672 672
        return classes.size() - 1;
673 673
      }
674 674
    }
675 675

	
676 676
    int newItem() {
677 677
      if (firstFreeItem != -1) {
678 678
        int idx = firstFreeItem;
679 679
        firstFreeItem = items[idx].next;
680 680
        return idx;
681 681
      } else {
682 682
        items.push_back(ItemT());
683 683
        return items.size() - 1;
684 684
      }
685 685
    }
686 686

	
687 687
  public:
688 688

	
689 689
    /// \brief Constructor
690 690
    ExtendFindEnum(ItemIntMap& _index)
691 691
      : index(_index), items(), firstFreeItem(-1),
692 692
        classes(), firstClass(-1), firstFreeClass(-1) {}
693 693

	
694 694
    /// \brief Inserts the given element into a new component.
695 695
    ///
696 696
    /// This method creates a new component consisting only of the
697 697
    /// given element.
698 698
    int insert(const Item& item) {
699 699
      int cdx = newClass();
700 700
      classes[cdx].prev = -1;
701 701
      classes[cdx].next = firstClass;
702 702
      if (firstClass != -1) {
703 703
        classes[firstClass].prev = cdx;
704 704
      }
705 705
      firstClass = cdx;
706 706

	
707 707
      int idx = newItem();
708 708
      items[idx].item = item;
709 709
      items[idx].cls = cdx;
710 710
      items[idx].prev = idx;
711 711
      items[idx].next = idx;
712 712

	
713 713
      classes[cdx].firstItem = idx;
714 714

	
715 715
      index.set(item, idx);
716 716

	
717 717
      return cdx;
718 718
    }
719 719

	
720 720
    /// \brief Inserts the given element into the given component.
721 721
    ///
722 722
    /// This methods inserts the element \e item a into the \e cls class.
723 723
    void insert(const Item& item, int cls) {
724 724
      int idx = newItem();
725 725
      int rdx = classes[cls].firstItem;
726 726
      items[idx].item = item;
727 727
      items[idx].cls = cls;
728 728

	
729 729
      items[idx].prev = rdx;
730 730
      items[idx].next = items[rdx].next;
731 731
      items[items[rdx].next].prev = idx;
732 732
      items[rdx].next = idx;
733 733

	
734 734
      index.set(item, idx);
735 735
    }
736 736

	
737 737
    /// \brief Clears the union-find data structure
738 738
    ///
739 739
    /// Erase each item from the data structure.
740 740
    void clear() {
741 741
      items.clear();
742
      classes.clear;
742
      classes.clear();
743 743
      firstClass = firstFreeClass = firstFreeItem = -1;
744 744
    }
745 745

	
746 746
    /// \brief Gives back the class of the \e item.
747 747
    ///
748 748
    /// Gives back the class of the \e item.
749 749
    int find(const Item &item) const {
750 750
      return items[index[item]].cls;
751 751
    }
752 752

	
753 753
    /// \brief Gives back a representant item of the component.
754 754
    ///
755 755
    /// Gives back a representant item of the component.
756 756
    Item item(int cls) const {
757 757
      return items[classes[cls].firstItem].item;
758 758
    }
759 759

	
760 760
    /// \brief Removes the given element from the structure.
761 761
    ///
762 762
    /// Removes the element from its component and if the component becomes
763 763
    /// empty then removes that component from the component list.
764 764
    ///
765 765
    /// \warning It is an error to remove an element which is not in
766 766
    /// the structure.
767 767
    void erase(const Item &item) {
768 768
      int idx = index[item];
769 769
      int cdx = items[idx].cls;
770 770

	
771 771
      if (idx == items[idx].next) {
772 772
        if (classes[cdx].prev != -1) {
773 773
          classes[classes[cdx].prev].next = classes[cdx].next;
774 774
        } else {
775 775
          firstClass = classes[cdx].next;
776 776
        }
777 777
        if (classes[cdx].next != -1) {
778 778
          classes[classes[cdx].next].prev = classes[cdx].prev;
779 779
        }
780 780
        classes[cdx].next = firstFreeClass;
781 781
        firstFreeClass = cdx;
782 782
      } else {
783 783
        classes[cdx].firstItem = items[idx].next;
784 784
        items[items[idx].next].prev = items[idx].prev;
785 785
        items[items[idx].prev].next = items[idx].next;
786 786
      }
787 787
      items[idx].next = firstFreeItem;
788 788
      firstFreeItem = idx;
789 789

	
790 790
    }
791 791

	
792 792

	
793 793
    /// \brief Removes the component of the given element from the structure.
794 794
    ///
795 795
    /// Removes the component of the given element from the structure.
796 796
    ///
797 797
    /// \warning It is an error to give an element which is not in the
798 798
    /// structure.
799 799
    void eraseClass(int cdx) {
800 800
      int idx = classes[cdx].firstItem;
801 801
      items[items[idx].prev].next = firstFreeItem;
802 802
      firstFreeItem = idx;
803 803

	
804 804
      if (classes[cdx].prev != -1) {
805 805
        classes[classes[cdx].prev].next = classes[cdx].next;
806 806
      } else {
807 807
        firstClass = classes[cdx].next;
808 808
      }
809 809
      if (classes[cdx].next != -1) {
810 810
        classes[classes[cdx].next].prev = classes[cdx].prev;
811 811
      }
812 812
      classes[cdx].next = firstFreeClass;
813 813
      firstFreeClass = cdx;
814 814
    }
815 815

	
816 816
    /// \brief LEMON style iterator for the classes.
817 817
    ///
818 818
    /// ClassIt is a lemon style iterator for the components. It iterates
819 819
    /// on the ids of classes.
820 820
    class ClassIt {
821 821
    public:
822 822
      /// \brief Constructor of the iterator
823 823
      ///
824 824
      /// Constructor of the iterator
825 825
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
826 826
        cdx = extendFind->firstClass;
827 827
      }
828 828

	
829 829
      /// \brief Constructor to get invalid iterator
830 830
      ///
831 831
      /// Constructor to get invalid iterator
832 832
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
833 833

	
834 834
      /// \brief Increment operator
835 835
      ///
836 836
      /// It steps to the next representant item.
837 837
      ClassIt& operator++() {
838 838
        cdx = extendFind->classes[cdx].next;
839 839
        return *this;
840 840
      }
841 841

	
842 842
      /// \brief Conversion operator
843 843
      ///
844 844
      /// It converts the iterator to the current class id.
845 845
      operator int() const {
846 846
        return cdx;
847 847
      }
848 848

	
849 849
      /// \brief Equality operator
850 850
      ///
851 851
      /// Equality operator
852 852
      bool operator==(const ClassIt& i) {
853 853
        return i.cdx == cdx;
854 854
      }
855 855

	
856 856
      /// \brief Inequality operator
857 857
      ///
858 858
      /// Inequality operator
859 859
      bool operator!=(const ClassIt& i) {
860 860
        return i.cdx != cdx;
861 861
      }
862 862

	
863 863
    private:
864 864
      const ExtendFindEnum* extendFind;
865 865
      int cdx;
866 866
    };
867 867

	
868 868
    /// \brief LEMON style iterator for the items of a component.
869 869
    ///
870 870
    /// ClassIt is a lemon style iterator for the components. It iterates
871 871
    /// on the items of a class. By example if you want to iterate on
872 872
    /// each items of each classes then you may write the next code.
873 873
    ///\code
874 874
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
875 875
    ///   std::cout << "Class: ";
876 876
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
877 877
    ///     std::cout << toString(iit) << ' ' << std::endl;
878 878
    ///   }
879 879
    ///   std::cout << std::endl;
880 880
    /// }
881 881
    ///\endcode
882 882
    class ItemIt {
883 883
    public:
884 884
      /// \brief Constructor of the iterator
885 885
      ///
886 886
      /// Constructor of the iterator. The iterator iterates
887 887
      /// on the class of the \c item.
888 888
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
889 889
        fdx = idx = extendFind->classes[cls].firstItem;
890 890
      }
891 891

	
892 892
      /// \brief Constructor to get invalid iterator
893 893
      ///
894 894
      /// Constructor to get invalid iterator
895 895
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
896 896

	
897 897
      /// \brief Increment operator
898 898
      ///
899 899
      /// It steps to the next item in the class.
900 900
      ItemIt& operator++() {
901 901
        idx = extendFind->items[idx].next;
902 902
        if (fdx == idx) idx = -1;
903 903
        return *this;
904 904
      }
905 905

	
906 906
      /// \brief Conversion operator
907 907
      ///
908 908
      /// It converts the iterator to the current item.
909 909
      operator const Item&() const {
910 910
        return extendFind->items[idx].item;
911 911
      }
912 912

	
913 913
      /// \brief Equality operator
914 914
      ///
915 915
      /// Equality operator
916 916
      bool operator==(const ItemIt& i) {
917 917
        return i.idx == idx;
918 918
      }
919 919

	
920 920
      /// \brief Inequality operator
921 921
      ///
922 922
      /// Inequality operator
923 923
      bool operator!=(const ItemIt& i) {
924 924
        return i.idx != idx;
925 925
      }
926 926

	
927 927
    private:
928 928
      const ExtendFindEnum* extendFind;
929 929
      int idx, fdx;
930 930
    };
931 931

	
932 932
  };
933 933

	
934 934
  /// \ingroup auxdat
935 935
  ///
936 936
  /// \brief A \e Union-Find data structure implementation which
937 937
  /// is able to store a priority for each item and retrieve the minimum of
938 938
  /// each class.
939 939
  ///
940 940
  /// A \e Union-Find data structure implementation which is able to
941 941
  /// store a priority for each item and retrieve the minimum of each
942 942
  /// class. In addition, it supports the joining and splitting the
943 943
  /// components. If you don't need this feature then you makes
944 944
  /// better to use the \ref UnionFind class which is more efficient.
945 945
  ///
946 946
  /// The union-find data strcuture based on a (2, 16)-tree with a
947 947
  /// tournament minimum selection on the internal nodes. The insert
948 948
  /// operation takes O(1), the find, set, decrease and increase takes
949 949
  /// O(log(n)), where n is the number of nodes in the current
950 950
  /// component.  The complexity of join and split is O(log(n)*k),
951 951
  /// where n is the sum of the number of the nodes and k is the
952 952
  /// number of joined components or the number of the components
953 953
  /// after the split.
954 954
  ///
955 955
  /// \pre You need to add all the elements by the \ref insert()
956 956
  /// method.
957 957
  template <typename V, typename IM, typename Comp = std::less<V> >
958 958
  class HeapUnionFind {
959 959
  public:
960 960

	
961 961
    ///\e
962 962
    typedef V Value;
963 963
    ///\e
964 964
    typedef typename IM::Key Item;
965 965
    ///\e
966 966
    typedef IM ItemIntMap;
967 967
    ///\e
968 968
    typedef Comp Compare;
969 969

	
970 970
  private:
971 971

	
972 972
    static const int cmax = 16;
973 973

	
974 974
    ItemIntMap& index;
975 975

	
976 976
    struct ClassNode {
977 977
      int parent;
978 978
      int depth;
979 979

	
980 980
      int left, right;
981 981
      int next, prev;
982 982
    };
983 983

	
984 984
    int first_class;
985 985
    int first_free_class;
986 986
    std::vector<ClassNode> classes;
987 987

	
988 988
    int newClass() {
989 989
      if (first_free_class < 0) {
990 990
        int id = classes.size();
991 991
        classes.push_back(ClassNode());
992 992
        return id;
993 993
      } else {
994 994
        int id = first_free_class;
995 995
        first_free_class = classes[id].next;
996 996
        return id;
997 997
      }
998 998
    }
999 999

	
1000 1000
    void deleteClass(int id) {
1001 1001
      classes[id].next = first_free_class;
1002 1002
      first_free_class = id;
1003 1003
    }
1004 1004

	
1005 1005
    struct ItemNode {
1006 1006
      int parent;
1007 1007
      Item item;
1008 1008
      Value prio;
1009 1009
      int next, prev;
1010 1010
      int left, right;
1011 1011
      int size;
1012 1012
    };
1013 1013

	
1014 1014
    int first_free_node;
1015 1015
    std::vector<ItemNode> nodes;
1016 1016

	
1017 1017
    int newNode() {
1018 1018
      if (first_free_node < 0) {
1019 1019
        int id = nodes.size();
1020 1020
        nodes.push_back(ItemNode());
1021 1021
        return id;
1022 1022
      } else {
1023 1023
        int id = first_free_node;
1024 1024
        first_free_node = nodes[id].next;
1025 1025
        return id;
1026 1026
      }
1027 1027
    }
1028 1028

	
1029 1029
    void deleteNode(int id) {
1030 1030
      nodes[id].next = first_free_node;
1031 1031
      first_free_node = id;
1032 1032
    }
1033 1033

	
1034 1034
    Comp comp;
1035 1035

	
1036 1036
    int findClass(int id) const {
1037 1037
      int kd = id;
1038 1038
      while (kd >= 0) {
1039 1039
        kd = nodes[kd].parent;
1040 1040
      }
1041 1041
      return ~kd;
1042 1042
    }
1043 1043

	
1044 1044
    int leftNode(int id) const {
1045 1045
      int kd = ~(classes[id].parent);
1046 1046
      for (int i = 0; i < classes[id].depth; ++i) {
1047 1047
        kd = nodes[kd].left;
1048 1048
      }
1049 1049
      return kd;
1050 1050
    }
1051 1051

	
1052 1052
    int nextNode(int id) const {
1053 1053
      int depth = 0;
1054 1054
      while (id >= 0 && nodes[id].next == -1) {
1055 1055
        id = nodes[id].parent;
1056 1056
        ++depth;
1057 1057
      }
1058 1058
      if (id < 0) {
1059 1059
        return -1;
1060 1060
      }
1061 1061
      id = nodes[id].next;
1062 1062
      while (depth--) {
1063 1063
        id = nodes[id].left;
1064 1064
      }
1065 1065
      return id;
1066 1066
    }
1067 1067

	
1068 1068

	
1069 1069
    void setPrio(int id) {
1070 1070
      int jd = nodes[id].left;
1071 1071
      nodes[id].prio = nodes[jd].prio;
1072 1072
      nodes[id].item = nodes[jd].item;
1073 1073
      jd = nodes[jd].next;
1074 1074
      while (jd != -1) {
1075 1075
        if (comp(nodes[jd].prio, nodes[id].prio)) {
1076 1076
          nodes[id].prio = nodes[jd].prio;
1077 1077
          nodes[id].item = nodes[jd].item;
1078 1078
        }
1079 1079
        jd = nodes[jd].next;
1080 1080
      }
1081 1081
    }
1082 1082

	
1083 1083
    void push(int id, int jd) {
1084 1084
      nodes[id].size = 1;
1085 1085
      nodes[id].left = nodes[id].right = jd;
1086 1086
      nodes[jd].next = nodes[jd].prev = -1;
1087 1087
      nodes[jd].parent = id;
1088 1088
    }
1089 1089

	
1090 1090
    void pushAfter(int id, int jd) {
1091 1091
      int kd = nodes[id].parent;
1092 1092
      if (nodes[id].next != -1) {
1093 1093
        nodes[nodes[id].next].prev = jd;
1094 1094
        if (kd >= 0) {
1095 1095
          nodes[kd].size += 1;
1096 1096
        }
1097 1097
      } else {
1098 1098
        if (kd >= 0) {
1099 1099
          nodes[kd].right = jd;
1100 1100
          nodes[kd].size += 1;
1101 1101
        }
1102 1102
      }
1103 1103
      nodes[jd].next = nodes[id].next;
1104 1104
      nodes[jd].prev = id;
1105 1105
      nodes[id].next = jd;
1106 1106
      nodes[jd].parent = kd;
1107 1107
    }
1108 1108

	
1109 1109
    void pushRight(int id, int jd) {
1110 1110
      nodes[id].size += 1;
1111 1111
      nodes[jd].prev = nodes[id].right;
1112 1112
      nodes[jd].next = -1;
1113 1113
      nodes[nodes[id].right].next = jd;
1114 1114
      nodes[id].right = jd;
1115 1115
      nodes[jd].parent = id;
1116 1116
    }
1117 1117

	
1118 1118
    void popRight(int id) {
1119 1119
      nodes[id].size -= 1;
1120 1120
      int jd = nodes[id].right;
1121 1121
      nodes[nodes[jd].prev].next = -1;
1122 1122
      nodes[id].right = nodes[jd].prev;
1123 1123
    }
1124 1124

	
1125 1125
    void splice(int id, int jd) {
1126 1126
      nodes[id].size += nodes[jd].size;
1127 1127
      nodes[nodes[id].right].next = nodes[jd].left;
1128 1128
      nodes[nodes[jd].left].prev = nodes[id].right;
1129 1129
      int kd = nodes[jd].left;
1130 1130
      while (kd != -1) {
1131 1131
        nodes[kd].parent = id;
1132 1132
        kd = nodes[kd].next;
1133 1133
      }
1134 1134
      nodes[id].right = nodes[jd].right;
1135 1135
    }
1136 1136

	
1137 1137
    void split(int id, int jd) {
1138 1138
      int kd = nodes[id].parent;
1139 1139
      nodes[kd].right = nodes[id].prev;
1140 1140
      nodes[nodes[id].prev].next = -1;
1141 1141

	
1142 1142
      nodes[jd].left = id;
1143 1143
      nodes[id].prev = -1;
1144 1144
      int num = 0;
1145 1145
      while (id != -1) {
1146 1146
        nodes[id].parent = jd;
1147 1147
        nodes[jd].right = id;
1148 1148
        id = nodes[id].next;
1149 1149
        ++num;
1150 1150
      }
1151 1151
      nodes[kd].size -= num;
1152 1152
      nodes[jd].size = num;
1153 1153
    }
1154 1154

	
1155 1155
    void pushLeft(int id, int jd) {
1156 1156
      nodes[id].size += 1;
1157 1157
      nodes[jd].next = nodes[id].left;
1158 1158
      nodes[jd].prev = -1;
1159 1159
      nodes[nodes[id].left].prev = jd;
1160 1160
      nodes[id].left = jd;
1161 1161
      nodes[jd].parent = id;
1162 1162
    }
1163 1163

	
1164 1164
    void popLeft(int id) {
1165 1165
      nodes[id].size -= 1;
1166 1166
      int jd = nodes[id].left;
1167 1167
      nodes[nodes[jd].next].prev = -1;
1168 1168
      nodes[id].left = nodes[jd].next;
1169 1169
    }
1170 1170

	
1171 1171
    void repairLeft(int id) {
1172 1172
      int jd = ~(classes[id].parent);
1173 1173
      while (nodes[jd].left != -1) {
1174 1174
        int kd = nodes[jd].left;
1175 1175
        if (nodes[jd].size == 1) {
1176 1176
          if (nodes[jd].parent < 0) {
1177 1177
            classes[id].parent = ~kd;
1178 1178
            classes[id].depth -= 1;
1179 1179
            nodes[kd].parent = ~id;
1180 1180
            deleteNode(jd);
1181 1181
            jd = kd;
1182 1182
          } else {
1183 1183
            int pd = nodes[jd].parent;
1184 1184
            if (nodes[nodes[jd].next].size < cmax) {
1185 1185
              pushLeft(nodes[jd].next, nodes[jd].left);
1186 1186
              if (less(jd, nodes[jd].next) ||
1187 1187
                  nodes[jd].item == nodes[pd].item) {
1188 1188
                nodes[nodes[jd].next].prio = nodes[jd].prio;
1189 1189
                nodes[nodes[jd].next].item = nodes[jd].item;
1190 1190
              }
1191 1191
              popLeft(pd);
1192 1192
              deleteNode(jd);
1193 1193
              jd = pd;
1194 1194
            } else {
1195 1195
              int ld = nodes[nodes[jd].next].left;
1196 1196
              popLeft(nodes[jd].next);
1197 1197
              pushRight(jd, ld);
1198 1198
              if (less(ld, nodes[jd].left) ||
1199 1199
                  nodes[ld].item == nodes[pd].item) {
1200 1200
                nodes[jd].item = nodes[ld].item;
1201 1201
                nodes[jd].prio = nodes[ld].prio;
1202 1202
              }
1203 1203
              if (nodes[nodes[jd].next].item == nodes[ld].item) {
1204 1204
                setPrio(nodes[jd].next);
1205 1205
              }
1206 1206
              jd = nodes[jd].left;
1207 1207
            }
1208 1208
          }
1209 1209
        } else {
1210 1210
          jd = nodes[jd].left;
1211 1211
        }
1212 1212
      }
1213 1213
    }
1214 1214

	
1215 1215
    void repairRight(int id) {
1216 1216
      int jd = ~(classes[id].parent);
1217 1217
      while (nodes[jd].right != -1) {
1218 1218
        int kd = nodes[jd].right;
1219 1219
        if (nodes[jd].size == 1) {
1220 1220
          if (nodes[jd].parent < 0) {
1221 1221
            classes[id].parent = ~kd;
1222 1222
            classes[id].depth -= 1;
1223 1223
            nodes[kd].parent = ~id;
1224 1224
            deleteNode(jd);
1225 1225
            jd = kd;
1226 1226
          } else {
1227 1227
            int pd = nodes[jd].parent;
1228 1228
            if (nodes[nodes[jd].prev].size < cmax) {
1229 1229
              pushRight(nodes[jd].prev, nodes[jd].right);
1230 1230
              if (less(jd, nodes[jd].prev) ||
1231 1231
                  nodes[jd].item == nodes[pd].item) {
1232 1232
                nodes[nodes[jd].prev].prio = nodes[jd].prio;
1233 1233
                nodes[nodes[jd].prev].item = nodes[jd].item;
1234 1234
              }
1235 1235
              popRight(pd);
1236 1236
              deleteNode(jd);
1237 1237
              jd = pd;
1238 1238
            } else {
1239 1239
              int ld = nodes[nodes[jd].prev].right;
1240 1240
              popRight(nodes[jd].prev);
1241 1241
              pushLeft(jd, ld);
1242 1242
              if (less(ld, nodes[jd].right) ||
1243 1243
                  nodes[ld].item == nodes[pd].item) {
1244 1244
                nodes[jd].item = nodes[ld].item;
1245 1245
                nodes[jd].prio = nodes[ld].prio;
1246 1246
              }
1247 1247
              if (nodes[nodes[jd].prev].item == nodes[ld].item) {
1248 1248
                setPrio(nodes[jd].prev);
1249 1249
              }
1250 1250
              jd = nodes[jd].right;
1251 1251
            }
1252 1252
          }
1253 1253
        } else {
1254 1254
          jd = nodes[jd].right;
1255 1255
        }
1256 1256
      }
1257 1257
    }
1258 1258

	
1259 1259

	
1260 1260
    bool less(int id, int jd) const {
1261 1261
      return comp(nodes[id].prio, nodes[jd].prio);
1262 1262
    }
1263 1263

	
1264 1264
  public:
1265 1265

	
1266 1266
    /// \brief Returns true when the given class is alive.
1267 1267
    ///
1268 1268
    /// Returns true when the given class is alive, ie. the class is
1269 1269
    /// not nested into other class.
1270 1270
    bool alive(int cls) const {
1271 1271
      return classes[cls].parent < 0;
1272 1272
    }
1273 1273

	
1274 1274
    /// \brief Returns true when the given class is trivial.
1275 1275
    ///
1276 1276
    /// Returns true when the given class is trivial, ie. the class
1277 1277
    /// contains just one item directly.
1278 1278
    bool trivial(int cls) const {
1279 1279
      return classes[cls].left == -1;
1280 1280
    }
1281 1281

	
1282 1282
    /// \brief Constructs the union-find.
1283 1283
    ///
1284 1284
    /// Constructs the union-find.
1285 1285
    /// \brief _index The index map of the union-find. The data
1286 1286
    /// structure uses internally for store references.
1287 1287
    HeapUnionFind(ItemIntMap& _index)
1288 1288
      : index(_index), first_class(-1),
1289 1289
        first_free_class(-1), first_free_node(-1) {}
1290 1290

	
1291 1291
    /// \brief Insert a new node into a new component.
1292 1292
    ///
1293 1293
    /// Insert a new node into a new component.
1294 1294
    /// \param item The item of the new node.
1295 1295
    /// \param prio The priority of the new node.
1296 1296
    /// \return The class id of the one-item-heap.
1297 1297
    int insert(const Item& item, const Value& prio) {
1298 1298
      int id = newNode();
1299 1299
      nodes[id].item = item;
1300 1300
      nodes[id].prio = prio;
1301 1301
      nodes[id].size = 0;
1302 1302

	
1303 1303
      nodes[id].prev = -1;
1304 1304
      nodes[id].next = -1;
1305 1305

	
1306 1306
      nodes[id].left = -1;
1307 1307
      nodes[id].right = -1;
1308 1308

	
1309 1309
      nodes[id].item = item;
1310 1310
      index[item] = id;
1311 1311

	
1312 1312
      int class_id = newClass();
1313 1313
      classes[class_id].parent = ~id;
1314 1314
      classes[class_id].depth = 0;
1315 1315

	
1316 1316
      classes[class_id].left = -1;
1317 1317
      classes[class_id].right = -1;
1318 1318

	
1319 1319
      if (first_class != -1) {
1320 1320
        classes[first_class].prev = class_id;
1321 1321
      }
1322 1322
      classes[class_id].next = first_class;
1323 1323
      classes[class_id].prev = -1;
1324 1324
      first_class = class_id;
1325 1325

	
1326 1326
      nodes[id].parent = ~class_id;
1327 1327

	
1328 1328
      return class_id;
1329 1329
    }
1330 1330

	
1331 1331
    /// \brief The class of the item.
1332 1332
    ///
1333 1333
    /// \return The alive class id of the item, which is not nested into
1334 1334
    /// other classes.
1335 1335
    ///
1336 1336
    /// The time complexity is O(log(n)).
1337 1337
    int find(const Item& item) const {
1338 1338
      return findClass(index[item]);
1339 1339
    }
1340 1340

	
1341 1341
    /// \brief Joins the classes.
1342 1342
    ///
1343 1343
    /// The current function joins the given classes. The parameter is
1344 1344
    /// an STL range which should be contains valid class ids. The
1345 1345
    /// time complexity is O(log(n)*k) where n is the overall number
1346 1346
    /// of the joined nodes and k is the number of classes.
1347 1347
    /// \return The class of the joined classes.
1348 1348
    /// \pre The range should contain at least two class ids.
1349 1349
    template <typename Iterator>
1350 1350
    int join(Iterator begin, Iterator end) {
1351 1351
      std::vector<int> cs;
1352 1352
      for (Iterator it = begin; it != end; ++it) {
1353 1353
        cs.push_back(*it);
1354 1354
      }
1355 1355

	
1356 1356
      int class_id = newClass();
1357 1357
      { // creation union-find
1358 1358

	
1359 1359
        if (first_class != -1) {
1360 1360
          classes[first_class].prev = class_id;
1361 1361
        }
1362 1362
        classes[class_id].next = first_class;
1363 1363
        classes[class_id].prev = -1;
1364 1364
        first_class = class_id;
1365 1365

	
1366 1366
        classes[class_id].depth = classes[cs[0]].depth;
1367 1367
        classes[class_id].parent = classes[cs[0]].parent;
1368 1368
        nodes[~(classes[class_id].parent)].parent = ~class_id;
1369 1369

	
1370 1370
        int l = cs[0];
1371 1371

	
1372 1372
        classes[class_id].left = l;
1373 1373
        classes[class_id].right = l;
1374 1374

	
1375 1375
        if (classes[l].next != -1) {
1376 1376
          classes[classes[l].next].prev = classes[l].prev;
1377 1377
        }
1378 1378
        classes[classes[l].prev].next = classes[l].next;
1379 1379

	
1380 1380
        classes[l].prev = -1;
1381 1381
        classes[l].next = -1;
1382 1382

	
1383 1383
        classes[l].depth = leftNode(l);
1384 1384
        classes[l].parent = class_id;
1385 1385

	
1386 1386
      }
1387 1387

	
1388 1388
      { // merging of heap
1389 1389
        int l = class_id;
1390 1390
        for (int ci = 1; ci < int(cs.size()); ++ci) {
1391 1391
          int r = cs[ci];
1392 1392
          int rln = leftNode(r);
1393 1393
          if (classes[l].depth > classes[r].depth) {
1394 1394
            int id = ~(classes[l].parent);
1395 1395
            for (int i = classes[r].depth + 1; i < classes[l].depth; ++i) {
1396 1396
              id = nodes[id].right;
1397 1397
            }
1398 1398
            while (id >= 0 && nodes[id].size == cmax) {
1399 1399
              int new_id = newNode();
1400 1400
              int right_id = nodes[id].right;
1401 1401

	
1402 1402
              popRight(id);
1403 1403
              if (nodes[id].item == nodes[right_id].item) {
1404 1404
                setPrio(id);
1405 1405
              }
1406 1406
              push(new_id, right_id);
1407 1407
              pushRight(new_id, ~(classes[r].parent));
1408 1408

	
1409 1409
              if (less(~classes[r].parent, right_id)) {
1410 1410
                nodes[new_id].item = nodes[~classes[r].parent].item;
1411 1411
                nodes[new_id].prio = nodes[~classes[r].parent].prio;
1412 1412
              } else {
1413 1413
                nodes[new_id].item = nodes[right_id].item;
1414 1414
                nodes[new_id].prio = nodes[right_id].prio;
1415 1415
              }
1416 1416

	
1417 1417
              id = nodes[id].parent;
1418 1418
              classes[r].parent = ~new_id;
1419 1419
            }
1420 1420
            if (id < 0) {
1421 1421
              int new_parent = newNode();
1422 1422
              nodes[new_parent].next = -1;
1423 1423
              nodes[new_parent].prev = -1;
1424 1424
              nodes[new_parent].parent = ~l;
1425 1425

	
1426 1426
              push(new_parent, ~(classes[l].parent));
1427 1427
              pushRight(new_parent, ~(classes[r].parent));
1428 1428
              setPrio(new_parent);
1429 1429

	
1430 1430
              classes[l].parent = ~new_parent;
1431 1431
              classes[l].depth += 1;
1432 1432
            } else {
1433 1433
              pushRight(id, ~(classes[r].parent));
1434 1434
              while (id >= 0 && less(~(classes[r].parent), id)) {
1435 1435
                nodes[id].prio = nodes[~(classes[r].parent)].prio;
1436 1436
                nodes[id].item = nodes[~(classes[r].parent)].item;
1437 1437
                id = nodes[id].parent;
1438 1438
              }
1439 1439
            }
1440 1440
          } else if (classes[r].depth > classes[l].depth) {
1441 1441
            int id = ~(classes[r].parent);
1442 1442
            for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) {
1443 1443
              id = nodes[id].left;
1444 1444
            }
1445 1445
            while (id >= 0 && nodes[id].size == cmax) {
1446 1446
              int new_id = newNode();
1447 1447
              int left_id = nodes[id].left;
1448 1448

	
1449 1449
              popLeft(id);
1450 1450
              if (nodes[id].prio == nodes[left_id].prio) {
1451 1451
                setPrio(id);
1452 1452
              }
1453 1453
              push(new_id, left_id);
1454 1454
              pushLeft(new_id, ~(classes[l].parent));
1455 1455

	
1456 1456
              if (less(~classes[l].parent, left_id)) {
1457 1457
                nodes[new_id].item = nodes[~classes[l].parent].item;
1458 1458
                nodes[new_id].prio = nodes[~classes[l].parent].prio;
1459 1459
              } else {
1460 1460
                nodes[new_id].item = nodes[left_id].item;
1461 1461
                nodes[new_id].prio = nodes[left_id].prio;
1462 1462
              }
1463 1463

	
1464 1464
              id = nodes[id].parent;
1465 1465
              classes[l].parent = ~new_id;
1466 1466

	
1467 1467
            }
1468 1468
            if (id < 0) {
1469 1469
              int new_parent = newNode();
1470 1470
              nodes[new_parent].next = -1;
1471 1471
              nodes[new_parent].prev = -1;
1472 1472
              nodes[new_parent].parent = ~l;
1473 1473

	
1474 1474
              push(new_parent, ~(classes[r].parent));
1475 1475
              pushLeft(new_parent, ~(classes[l].parent));
1476 1476
              setPrio(new_parent);
1477 1477

	
1478 1478
              classes[r].parent = ~new_parent;
1479 1479
              classes[r].depth += 1;
1480 1480
            } else {
1481 1481
              pushLeft(id, ~(classes[l].parent));
1482 1482
              while (id >= 0 && less(~(classes[l].parent), id)) {
1483 1483
                nodes[id].prio = nodes[~(classes[l].parent)].prio;
1484 1484
                nodes[id].item = nodes[~(classes[l].parent)].item;
1485 1485
                id = nodes[id].parent;
1486 1486
              }
1487 1487
            }
1488 1488
            nodes[~(classes[r].parent)].parent = ~l;
1489 1489
            classes[l].parent = classes[r].parent;
1490 1490
            classes[l].depth = classes[r].depth;
1491 1491
          } else {
1492 1492
            if (classes[l].depth != 0 &&
1493 1493
                nodes[~(classes[l].parent)].size +
1494 1494
                nodes[~(classes[r].parent)].size <= cmax) {
1495 1495
              splice(~(classes[l].parent), ~(classes[r].parent));
1496 1496
              deleteNode(~(classes[r].parent));
1497 1497
              if (less(~(classes[r].parent), ~(classes[l].parent))) {
1498 1498
                nodes[~(classes[l].parent)].prio =
1499 1499
                  nodes[~(classes[r].parent)].prio;
1500 1500
                nodes[~(classes[l].parent)].item =
1501 1501
                  nodes[~(classes[r].parent)].item;
1502 1502
              }
1503 1503
            } else {
1504 1504
              int new_parent = newNode();
1505 1505
              nodes[new_parent].next = nodes[new_parent].prev = -1;
1506 1506
              push(new_parent, ~(classes[l].parent));
1507 1507
              pushRight(new_parent, ~(classes[r].parent));
1508 1508
              setPrio(new_parent);
1509 1509

	
1510 1510
              classes[l].parent = ~new_parent;
Ignore white space 1536 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
LINK_DIRECTORIES(
7 7
  ${PROJECT_BINARY_DIR}/lemon
8 8
)
9 9

	
10 10
SET(TESTS
11 11
  adaptors_test
12 12
  bellman_ford_test
13 13
  bfs_test
14 14
  circulation_test
15 15
  connectivity_test
16 16
  counter_test
17 17
  dfs_test
18 18
  digraph_test
19 19
  dijkstra_test
20 20
  dim_test
21 21
  edge_set_test
22 22
  error_test
23 23
  euler_test
24 24
  gomory_hu_test
25 25
  graph_copy_test
26 26
  graph_test
27 27
  graph_utils_test
28 28
  hao_orlin_test
29 29
  heap_test
30 30
  kruskal_test
31 31
  maps_test
32 32
  matching_test
33 33
  min_cost_arborescence_test
34 34
  min_cost_flow_test
35 35
  min_mean_cycle_test
36 36
  path_test
37
  planarity_test
37 38
  preflow_test
38 39
  radix_sort_test
39 40
  random_test
40 41
  suurballe_test
41 42
  time_measure_test
42 43
  unionfind_test
43 44
)
44 45

	
45 46
IF(LEMON_HAVE_LP)
46 47
  ADD_EXECUTABLE(lp_test lp_test.cc)
47 48
  SET(LP_TEST_LIBS lemon)
48 49

	
49 50
  IF(LEMON_HAVE_GLPK)
50 51
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
51 52
  ENDIF()
52 53
  IF(LEMON_HAVE_CPLEX)
53 54
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
54 55
  ENDIF()
55 56
  IF(LEMON_HAVE_CLP)
56 57
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
57 58
  ENDIF()
58 59

	
59 60
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
60 61
  ADD_TEST(lp_test lp_test)
61 62

	
62 63
  IF(WIN32 AND LEMON_HAVE_GLPK)
63 64
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
64 65
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
65 66
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
66 67
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
67 68
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
68 69
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
69 70
    )
70 71
  ENDIF()
71 72

	
72 73
  IF(WIN32 AND LEMON_HAVE_CPLEX)
73 74
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
74 75
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
75 76
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
76 77
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
77 78
    )
78 79
  ENDIF()
79 80
ENDIF()
80 81

	
81 82
IF(LEMON_HAVE_MIP)
82 83
  ADD_EXECUTABLE(mip_test mip_test.cc)
83 84
  SET(MIP_TEST_LIBS lemon)
84 85

	
85 86
  IF(LEMON_HAVE_GLPK)
86 87
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
87 88
  ENDIF()
88 89
  IF(LEMON_HAVE_CPLEX)
89 90
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
90 91
  ENDIF()
91 92
  IF(LEMON_HAVE_CBC)
92 93
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
93 94
  ENDIF()
94 95

	
95 96
  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
96 97
  ADD_TEST(mip_test mip_test)
97 98

	
98 99
  IF(WIN32 AND LEMON_HAVE_GLPK)
99 100
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
100 101
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
101 102
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
102 103
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
103 104
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
104 105
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
105 106
    )
106 107
  ENDIF()
107 108

	
108 109
  IF(WIN32 AND LEMON_HAVE_CPLEX)
109 110
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
110 111
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
111 112
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
112 113
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
113 114
    )
114 115
  ENDIF()
115 116
ENDIF()
116 117

	
117 118
FOREACH(TEST_NAME ${TESTS})
118 119
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
119 120
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
120 121
  ADD_TEST(${TEST_NAME} ${TEST_NAME})
121 122
ENDFOREACH()
Ignore white space 6 line context
1 1
if USE_VALGRIND
2 2
TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
3 3
endif
4 4

	
5 5
EXTRA_DIST += \
6 6
	test/CMakeLists.txt
7 7

	
8 8
noinst_HEADERS += \
9 9
	test/graph_test.h \
10 10
	test/test_tools.h
11 11

	
12 12
check_PROGRAMS += \
13 13
	test/adaptors_test \
14 14
	test/bellman_ford_test \
15 15
	test/bfs_test \
16 16
	test/circulation_test \
17 17
	test/connectivity_test \
18 18
	test/counter_test \
19 19
	test/dfs_test \
20 20
	test/digraph_test \
21 21
	test/dijkstra_test \
22 22
	test/dim_test \
23 23
	test/edge_set_test \
24 24
	test/error_test \
25 25
	test/euler_test \
26 26
	test/gomory_hu_test \
27 27
	test/graph_copy_test \
28 28
	test/graph_test \
29 29
	test/graph_utils_test \
30 30
	test/hao_orlin_test \
31 31
	test/heap_test \
32 32
	test/kruskal_test \
33 33
	test/maps_test \
34 34
	test/matching_test \
35 35
	test/min_cost_arborescence_test \
36 36
	test/min_cost_flow_test \
37 37
	test/min_mean_cycle_test \
38 38
	test/path_test \
39
	test/planarity_test \
39 40
	test/preflow_test \
40 41
	test/radix_sort_test \
41 42
	test/random_test \
42 43
	test/suurballe_test \
43 44
	test/test_tools_fail \
44 45
	test/test_tools_pass \
45 46
	test/time_measure_test \
46 47
	test/unionfind_test
47 48

	
48 49
test_test_tools_pass_DEPENDENCIES = demo
49 50

	
50 51
if HAVE_LP
51 52
check_PROGRAMS += test/lp_test
52 53
endif HAVE_LP
53 54
if HAVE_MIP
54 55
check_PROGRAMS += test/mip_test
55 56
endif HAVE_MIP
56 57

	
57 58
TESTS += $(check_PROGRAMS)
58 59
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
59 60

	
60 61
test_adaptors_test_SOURCES = test/adaptors_test.cc
61 62
test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
62 63
test_bfs_test_SOURCES = test/bfs_test.cc
63 64
test_circulation_test_SOURCES = test/circulation_test.cc
64 65
test_counter_test_SOURCES = test/counter_test.cc
65 66
test_connectivity_test_SOURCES = test/connectivity_test.cc
66 67
test_dfs_test_SOURCES = test/dfs_test.cc
67 68
test_digraph_test_SOURCES = test/digraph_test.cc
68 69
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
69 70
test_dim_test_SOURCES = test/dim_test.cc
70 71
test_edge_set_test_SOURCES = test/edge_set_test.cc
71 72
test_error_test_SOURCES = test/error_test.cc
72 73
test_euler_test_SOURCES = test/euler_test.cc
73 74
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
74 75
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
75 76
test_graph_test_SOURCES = test/graph_test.cc
76 77
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
77 78
test_heap_test_SOURCES = test/heap_test.cc
78 79
test_kruskal_test_SOURCES = test/kruskal_test.cc
79 80
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
80 81
test_lp_test_SOURCES = test/lp_test.cc
81 82
test_maps_test_SOURCES = test/maps_test.cc
82 83
test_mip_test_SOURCES = test/mip_test.cc
83 84
test_matching_test_SOURCES = test/matching_test.cc
84 85
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
85 86
test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
86 87
test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
87 88
test_path_test_SOURCES = test/path_test.cc
89
test_planarity_test_SOURCES = test/planarity_test.cc
88 90
test_preflow_test_SOURCES = test/preflow_test.cc
89 91
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
90 92
test_suurballe_test_SOURCES = test/suurballe_test.cc
91 93
test_random_test_SOURCES = test/random_test.cc
92 94
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
93 95
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
94 96
test_time_measure_test_SOURCES = test/time_measure_test.cc
95 97
test_unionfind_test_SOURCES = test/unionfind_test.cc
0 comments (0 inline)