lemon/planarity.h
author kpeter
Thu, 13 Nov 2008 16:17:50 +0000
changeset 2630 d239741cfd44
parent 2553 bfced05fa852
permissions -rw-r--r--
Various improvements in NetworkSimplex.

- Faster variant of "Altering Candidate List" pivot rule using make_heap
instead of partial_sort.
- Doc improvements.
- Removing unecessary inline keywords.
deba@2480
     1
/* -*- C++ -*-
deba@2480
     2
 *
deba@2480
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2480
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
deba@2480
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2480
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2480
     8
 *
deba@2480
     9
 * Permission to use, modify and distribute this software is granted
deba@2480
    10
 * provided that this copyright notice appears in all copies. For
deba@2480
    11
 * precise terms see the accompanying LICENSE file.
deba@2480
    12
 *
deba@2480
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2480
    14
 * express or implied, and with no claim as to its suitability for any
deba@2480
    15
 * purpose.
deba@2480
    16
 *
deba@2480
    17
 */
alpar@2553
    18
deba@2480
    19
#ifndef LEMON_PLANARITY_H
deba@2480
    20
#define LEMON_PLANARITY_H
deba@2480
    21
deba@2499
    22
/// \ingroup planar
deba@2480
    23
/// \file
deba@2508
    24
/// \brief Planarity checking, embedding, drawing and coloring
deba@2480
    25
deba@2480
    26
#include <vector>
deba@2480
    27
#include <list>
deba@2480
    28
deba@2480
    29
#include <lemon/dfs.h>
deba@2508
    30
#include <lemon/bfs.h>
deba@2480
    31
#include <lemon/radix_sort.h>
deba@2480
    32
#include <lemon/maps.h>
deba@2480
    33
#include <lemon/path.h>
deba@2499
    34
#include <lemon/iterable_maps.h>
deba@2499
    35
#include <lemon/edge_set.h>
deba@2508
    36
#include <lemon/bucket_heap.h>
deba@2508
    37
#include <lemon/ugraph_adaptor.h>
deba@2508
    38
#include <lemon/color.h>
deba@2480
    39
deba@2480
    40
deba@2480
    41
namespace lemon {
deba@2480
    42
deba@2480
    43
  namespace _planarity_bits {
deba@2480
    44
deba@2480
    45
    template <typename UGraph>
deba@2480
    46
    struct PlanarityVisitor : DfsVisitor<UGraph> {
deba@2480
    47
deba@2480
    48
      typedef typename UGraph::Node Node;
deba@2480
    49
      typedef typename UGraph::Edge Edge;
deba@2480
    50
deba@2480
    51
      typedef typename UGraph::template NodeMap<Edge> PredMap;
deba@2480
    52
deba@2480
    53
      typedef typename UGraph::template UEdgeMap<bool> TreeMap;
deba@2480
    54
deba@2480
    55
      typedef typename UGraph::template NodeMap<int> OrderMap;
deba@2480
    56
      typedef std::vector<Node> OrderList;
deba@2480
    57
deba@2480
    58
      typedef typename UGraph::template NodeMap<int> LowMap;
deba@2480
    59
      typedef typename UGraph::template NodeMap<int> AncestorMap;
deba@2480
    60
deba@2480
    61
      PlanarityVisitor(const UGraph& ugraph,
deba@2480
    62
		       PredMap& pred_map, TreeMap& tree_map,
deba@2480
    63
		       OrderMap& order_map, OrderList& order_list,
deba@2480
    64
		       AncestorMap& ancestor_map, LowMap& low_map)
deba@2480
    65
	: _ugraph(ugraph), _pred_map(pred_map), _tree_map(tree_map),
deba@2480
    66
	  _order_map(order_map), _order_list(order_list),
deba@2480
    67
	  _ancestor_map(ancestor_map), _low_map(low_map) {}
deba@2480
    68
      
deba@2480
    69
      void reach(const Node& node) {
deba@2480
    70
	_order_map[node] = _order_list.size();
deba@2480
    71
	_low_map[node] = _order_list.size();
deba@2480
    72
	_ancestor_map[node] = _order_list.size();
deba@2480
    73
	_order_list.push_back(node);
deba@2480
    74
      }
deba@2480
    75
deba@2480
    76
      void discover(const Edge& edge) {
deba@2480
    77
	Node source = _ugraph.source(edge);
deba@2480
    78
	Node target = _ugraph.target(edge);
deba@2480
    79
deba@2480
    80
	_tree_map[edge] = true;
deba@2480
    81
	_pred_map[target] = edge;
deba@2480
    82
      }
deba@2480
    83
deba@2480
    84
      void examine(const Edge& edge) {
deba@2480
    85
	Node source = _ugraph.source(edge);
deba@2480
    86
	Node target = _ugraph.target(edge);
deba@2480
    87
	
deba@2480
    88
	if (_order_map[target] < _order_map[source] && !_tree_map[edge]) {
deba@2480
    89
	  if (_low_map[source] > _order_map[target]) {
deba@2480
    90
	    _low_map[source] = _order_map[target];
deba@2480
    91
	  }
deba@2480
    92
	  if (_ancestor_map[source] > _order_map[target]) {
deba@2480
    93
	    _ancestor_map[source] = _order_map[target];
deba@2480
    94
	  }
deba@2480
    95
	}
deba@2480
    96
      }
deba@2480
    97
deba@2480
    98
      void backtrack(const Edge& edge) {
deba@2480
    99
	Node source = _ugraph.source(edge);
deba@2480
   100
	Node target = _ugraph.target(edge);
deba@2480
   101
deba@2480
   102
	if (_low_map[source] > _low_map[target]) {
deba@2480
   103
	  _low_map[source] = _low_map[target];
deba@2480
   104
	}
deba@2480
   105
      }
deba@2480
   106
deba@2480
   107
      const UGraph& _ugraph;
deba@2480
   108
      PredMap& _pred_map;
deba@2480
   109
      TreeMap& _tree_map;
deba@2480
   110
      OrderMap& _order_map;
deba@2480
   111
      OrderList& _order_list;
deba@2480
   112
      AncestorMap& _ancestor_map;
deba@2480
   113
      LowMap& _low_map;
deba@2480
   114
    };
deba@2480
   115
deba@2480
   116
    template <typename UGraph, bool embedding = true>
deba@2480
   117
    struct NodeDataNode {
deba@2480
   118
      int prev, next;
deba@2480
   119
      int visited;
deba@2480
   120
      typename UGraph::Edge first;
deba@2480
   121
      bool inverted;
deba@2480
   122
    };
deba@2480
   123
deba@2480
   124
    template <typename UGraph>
deba@2480
   125
    struct NodeDataNode<UGraph, false> {
deba@2480
   126
      int prev, next;
deba@2480
   127
      int visited;
deba@2480
   128
    };
deba@2480
   129
deba@2480
   130
    template <typename UGraph>
deba@2480
   131
    struct ChildListNode {
deba@2480
   132
      typedef typename UGraph::Node Node;
deba@2480
   133
      Node first;
deba@2480
   134
      Node prev, next;
deba@2480
   135
    };
deba@2480
   136
deba@2480
   137
    template <typename UGraph>
deba@2480
   138
    struct EdgeListNode {
deba@2480
   139
      typename UGraph::Edge prev, next;
deba@2480
   140
    };
deba@2480
   141
deba@2480
   142
  }
deba@2480
   143
deba@2499
   144
  /// \ingroup planar
deba@2480
   145
  ///
deba@2480
   146
  /// \brief Planarity checking of an undirected simple graph
deba@2480
   147
  ///
deba@2499
   148
  /// This class implements the Boyer-Myrvold algorithm for planarity
deba@2480
   149
  /// checking of an undirected graph. This class is a simplified
deba@2480
   150
  /// version of the PlanarEmbedding algorithm class, and it does
deba@2480
   151
  /// provide neither embedding nor kuratowski subdivisons.
deba@2480
   152
  template <typename UGraph>
deba@2480
   153
  class PlanarityChecking {
deba@2480
   154
  private:
deba@2480
   155
    
deba@2499
   156
    UGRAPH_TYPEDEFS(typename UGraph);
deba@2480
   157
      
deba@2480
   158
    const UGraph& _ugraph;
deba@2480
   159
deba@2480
   160
  private:
deba@2480
   161
deba@2480
   162
    typedef typename UGraph::template NodeMap<Edge> PredMap;
deba@2480
   163
    
deba@2480
   164
    typedef typename UGraph::template UEdgeMap<bool> TreeMap;
deba@2480
   165
deba@2480
   166
    typedef typename UGraph::template NodeMap<int> OrderMap;
deba@2480
   167
    typedef std::vector<Node> OrderList;
deba@2480
   168
deba@2480
   169
    typedef typename UGraph::template NodeMap<int> LowMap;
deba@2480
   170
    typedef typename UGraph::template NodeMap<int> AncestorMap;
deba@2480
   171
deba@2480
   172
    typedef _planarity_bits::NodeDataNode<UGraph> NodeDataNode;
deba@2480
   173
    typedef std::vector<NodeDataNode> NodeData;
deba@2480
   174
    
deba@2480
   175
    typedef _planarity_bits::ChildListNode<UGraph> ChildListNode;
deba@2480
   176
    typedef typename UGraph::template NodeMap<ChildListNode> ChildLists;
deba@2480
   177
deba@2480
   178
    typedef typename UGraph::template NodeMap<std::list<int> > MergeRoots;
deba@2480
   179
 
deba@2480
   180
    typedef typename UGraph::template NodeMap<bool> EmbedEdge;
deba@2480
   181
deba@2480
   182
  public:
deba@2480
   183
deba@2480
   184
    /// \brief Constructor
deba@2480
   185
    ///
deba@2480
   186
    /// \warining The graph should be simple, i.e. parallel and loop edge
deba@2480
   187
    /// free.
deba@2480
   188
    PlanarityChecking(const UGraph& ugraph) : _ugraph(ugraph) {}
deba@2480
   189
deba@2480
   190
    /// \brief Runs the algorithm.
deba@2480
   191
    ///
deba@2480
   192
    /// Runs the algorithm.  
deba@2480
   193
    /// \return %True when the graph is planar.
deba@2481
   194
    bool run() {
deba@2480
   195
      typedef _planarity_bits::PlanarityVisitor<UGraph> Visitor;
deba@2480
   196
deba@2480
   197
      PredMap pred_map(_ugraph, INVALID);
deba@2480
   198
      TreeMap tree_map(_ugraph, false);
deba@2480
   199
deba@2480
   200
      OrderMap order_map(_ugraph, -1);
deba@2480
   201
      OrderList order_list;
deba@2480
   202
deba@2480
   203
      AncestorMap ancestor_map(_ugraph, -1);
deba@2480
   204
      LowMap low_map(_ugraph, -1);
deba@2480
   205
deba@2480
   206
      Visitor visitor(_ugraph, pred_map, tree_map,
deba@2480
   207
		      order_map, order_list, ancestor_map, low_map);
deba@2480
   208
      DfsVisit<UGraph, Visitor> visit(_ugraph, visitor);
deba@2480
   209
      visit.run();
deba@2480
   210
deba@2480
   211
      ChildLists child_lists(_ugraph);
deba@2480
   212
      createChildLists(tree_map, order_map, low_map, child_lists);
deba@2480
   213
deba@2480
   214
      NodeData node_data(2 * order_list.size());
deba@2480
   215
      
deba@2480
   216
      EmbedEdge embed_edge(_ugraph, false);
deba@2480
   217
deba@2480
   218
      MergeRoots merge_roots(_ugraph);
deba@2480
   219
      
deba@2480
   220
      for (int i = order_list.size() - 1; i >= 0; --i) {
deba@2480
   221
deba@2480
   222
	Node node = order_list[i];
deba@2480
   223
deba@2480
   224
	Node source = node;
deba@2480
   225
	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
deba@2480
   226
	  Node target = _ugraph.target(e);
deba@2480
   227
	  
deba@2480
   228
	  if (order_map[source] < order_map[target] && tree_map[e]) {
deba@2481
   229
	    initFace(target, node_data, order_map, order_list);
deba@2480
   230
	  }
deba@2480
   231
	}
deba@2480
   232
	
deba@2480
   233
	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
deba@2480
   234
	  Node target = _ugraph.target(e);
deba@2480
   235
	  
deba@2480
   236
	  if (order_map[source] < order_map[target] && !tree_map[e]) {
deba@2480
   237
	    embed_edge[target] = true;
deba@2480
   238
	    walkUp(target, source, i, pred_map, low_map,
deba@2480
   239
		   order_map, order_list, node_data, merge_roots);
deba@2480
   240
	  }
deba@2480
   241
	}
deba@2480
   242
deba@2480
   243
	for (typename MergeRoots::Value::iterator it = 
deba@2480
   244
	       merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
deba@2480
   245
	  int rn = *it;
deba@2480
   246
	  walkDown(rn, i, node_data, order_list, child_lists, 
deba@2480
   247
		   ancestor_map, low_map, embed_edge, merge_roots);
deba@2480
   248
	}
deba@2480
   249
	merge_roots[node].clear();
deba@2480
   250
	
deba@2480
   251
	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
deba@2480
   252
	  Node target = _ugraph.target(e);
deba@2480
   253
	  
deba@2480
   254
	  if (order_map[source] < order_map[target] && !tree_map[e]) {
deba@2480
   255
	    if (embed_edge[target]) {
deba@2480
   256
	      return false;
deba@2480
   257
	    }
deba@2480
   258
	  }
deba@2480
   259
	}
deba@2480
   260
      }
deba@2480
   261
deba@2480
   262
      return true;
deba@2480
   263
    }
deba@2480
   264
    
deba@2480
   265
  private:
deba@2480
   266
deba@2480
   267
    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
deba@2480
   268
			  const LowMap& low_map, ChildLists& child_lists) {
deba@2480
   269
deba@2480
   270
      for (NodeIt n(_ugraph); n != INVALID; ++n) {
deba@2480
   271
	Node source = n;
deba@2480
   272
	
deba@2480
   273
	std::vector<Node> targets;  
deba@2480
   274
	for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
deba@2480
   275
	  Node target = _ugraph.target(e);
deba@2480
   276
deba@2480
   277
	  if (order_map[source] < order_map[target] && tree_map[e]) {
deba@2480
   278
	    targets.push_back(target);
deba@2480
   279
	  }
deba@2480
   280
	}	
deba@2480
   281
deba@2480
   282
	if (targets.size() == 0) {
deba@2480
   283
	  child_lists[source].first = INVALID;
deba@2480
   284
	} else if (targets.size() == 1) {
deba@2480
   285
	  child_lists[source].first = targets[0];
deba@2480
   286
	  child_lists[targets[0]].prev = INVALID;
deba@2480
   287
	  child_lists[targets[0]].next = INVALID;
deba@2480
   288
	} else {
deba@2480
   289
	  radixSort(targets.begin(), targets.end(), mapFunctor(low_map));
deba@2480
   290
	  for (int i = 1; i < int(targets.size()); ++i) {
deba@2480
   291
	    child_lists[targets[i]].prev = targets[i - 1];
deba@2480
   292
	    child_lists[targets[i - 1]].next = targets[i];
deba@2480
   293
	  }
deba@2480
   294
	  child_lists[targets.back()].next = INVALID; 
deba@2480
   295
	  child_lists[targets.front()].prev = INVALID;
deba@2480
   296
	  child_lists[source].first = targets.front();
deba@2480
   297
	}
deba@2480
   298
      }
deba@2480
   299
    }
deba@2480
   300
deba@2480
   301
    void walkUp(const Node& node, Node root, int rorder,
deba@2480
   302
		const PredMap& pred_map, const LowMap& low_map,
deba@2480
   303
		const OrderMap& order_map, const OrderList& order_list,
deba@2480
   304
		NodeData& node_data, MergeRoots& merge_roots) {
deba@2480
   305
deba@2480
   306
      int na, nb;
deba@2480
   307
      bool da, db;
deba@2480
   308
      
deba@2480
   309
      na = nb = order_map[node];
deba@2480
   310
      da = true; db = false;
deba@2480
   311
      
deba@2480
   312
      while (true) {
deba@2480
   313
	
deba@2480
   314
	if (node_data[na].visited == rorder) break;
deba@2480
   315
	if (node_data[nb].visited == rorder) break;
deba@2480
   316
deba@2480
   317
	node_data[na].visited = rorder;
deba@2480
   318
	node_data[nb].visited = rorder;
deba@2480
   319
deba@2480
   320
	int rn = -1;
deba@2480
   321
deba@2480
   322
	if (na >= int(order_list.size())) {
deba@2480
   323
	  rn = na;
deba@2480
   324
	} else if (nb >= int(order_list.size())) {
deba@2480
   325
	  rn = nb;
deba@2480
   326
	}
deba@2480
   327
deba@2480
   328
	if (rn == -1) {
deba@2480
   329
	  int nn;
deba@2480
   330
	  
deba@2480
   331
	  nn = da ? node_data[na].prev : node_data[na].next;
deba@2480
   332
	  da = node_data[nn].prev != na;
deba@2480
   333
	  na = nn;
deba@2480
   334
	  
deba@2480
   335
	  nn = db ? node_data[nb].prev : node_data[nb].next;
deba@2480
   336
	  db = node_data[nn].prev != nb;
deba@2480
   337
	  nb = nn;
deba@2480
   338
deba@2480
   339
	} else {
deba@2480
   340
deba@2480
   341
	  Node rep = order_list[rn - order_list.size()];
deba@2480
   342
	  Node parent = _ugraph.source(pred_map[rep]);
deba@2480
   343
deba@2480
   344
	  if (low_map[rep] < rorder) {
deba@2480
   345
	    merge_roots[parent].push_back(rn);
deba@2480
   346
	  } else {
deba@2480
   347
	    merge_roots[parent].push_front(rn);
deba@2480
   348
	  }
deba@2480
   349
	  
deba@2480
   350
	  if (parent != root) {  
deba@2480
   351
	    na = nb = order_map[parent];
deba@2480
   352
	    da = true; db = false;
deba@2480
   353
	  } else {
deba@2480
   354
	    break;
deba@2480
   355
	  }
deba@2480
   356
	}	
deba@2480
   357
      }
deba@2480
   358
    }
deba@2480
   359
deba@2480
   360
    void walkDown(int rn, int rorder, NodeData& node_data,
deba@2480
   361
		  OrderList& order_list, ChildLists& child_lists,
deba@2480
   362
		  AncestorMap& ancestor_map, LowMap& low_map,
deba@2480
   363
		  EmbedEdge& embed_edge, MergeRoots& merge_roots) {
deba@2480
   364
deba@2480
   365
      std::vector<std::pair<int, bool> > merge_stack;
deba@2480
   366
deba@2480
   367
      for (int di = 0; di < 2; ++di) {
deba@2480
   368
	bool rd = di == 0;
deba@2480
   369
	int pn = rn;
deba@2480
   370
	int n = rd ? node_data[rn].next : node_data[rn].prev;
deba@2480
   371
	
deba@2480
   372
	while (n != rn) {
deba@2480
   373
	  
deba@2480
   374
	  Node node = order_list[n];
deba@2480
   375
	  
deba@2480
   376
	  if (embed_edge[node]) {
deba@2480
   377
deba@2480
   378
	    // Merging components on the critical path
deba@2480
   379
	    while (!merge_stack.empty()) {
deba@2480
   380
deba@2480
   381
	      // Component root
deba@2480
   382
	      int cn = merge_stack.back().first;
deba@2480
   383
	      bool cd = merge_stack.back().second;
deba@2480
   384
	      merge_stack.pop_back();
deba@2480
   385
deba@2480
   386
	      // Parent of component
deba@2480
   387
	      int dn = merge_stack.back().first;
deba@2480
   388
	      bool dd = merge_stack.back().second;
deba@2480
   389
	      merge_stack.pop_back();
deba@2480
   390
deba@2480
   391
	      Node parent = order_list[dn];
deba@2480
   392
deba@2480
   393
	      // Erasing from merge_roots
deba@2480
   394
	      merge_roots[parent].pop_front();
deba@2480
   395
	      
deba@2480
   396
	      Node child = order_list[cn - order_list.size()];
deba@2480
   397
deba@2480
   398
	      // Erasing from child_lists
deba@2480
   399
	      if (child_lists[child].prev != INVALID) {
deba@2480
   400
		child_lists[child_lists[child].prev].next =
deba@2480
   401
		  child_lists[child].next;
deba@2480
   402
	      } else {
deba@2480
   403
		child_lists[parent].first = child_lists[child].next;
deba@2480
   404
	      }
deba@2480
   405
	      
deba@2480
   406
	      if (child_lists[child].next != INVALID) {
deba@2480
   407
		child_lists[child_lists[child].next].prev =
deba@2480
   408
		  child_lists[child].prev;
deba@2480
   409
	      }
deba@2480
   410
	      
deba@2480
   411
	      // Merging external faces
deba@2480
   412
	      {
deba@2480
   413
		int en = cn;
deba@2480
   414
		cn = cd ? node_data[cn].prev : node_data[cn].next;
deba@2480
   415
		cd = node_data[cn].next == en;
deba@2480
   416
deba@2480
   417
	      }
deba@2480
   418
deba@2480
   419
	      if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
deba@2480
   420
	      if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
deba@2480
   421
deba@2480
   422
	    }
deba@2480
   423
deba@2480
   424
	    bool d = pn == node_data[n].prev;
deba@2480
   425
deba@2480
   426
	    if (node_data[n].prev == node_data[n].next && 
deba@2480
   427
		node_data[n].inverted) {
deba@2480
   428
	      d = !d;
deba@2480
   429
	    }
deba@2480
   430
deba@2480
   431
	    // Embedding edge into external face
deba@2480
   432
	    if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
deba@2480
   433
	    if (d) node_data[n].prev = rn; else node_data[n].next = rn;
deba@2480
   434
	    pn = rn;
deba@2480
   435
deba@2480
   436
	    embed_edge[order_list[n]] = false;
deba@2480
   437
	  }
deba@2480
   438
deba@2480
   439
	  if (!merge_roots[node].empty()) {
deba@2480
   440
deba@2480
   441
	    bool d = pn == node_data[n].prev;
deba@2480
   442
deba@2480
   443
	    merge_stack.push_back(std::make_pair(n, d));
deba@2480
   444
deba@2480
   445
	    int rn = merge_roots[node].front();
deba@2480
   446
	    
deba@2480
   447
	    int xn = node_data[rn].next;
deba@2480
   448
	    Node xnode = order_list[xn];
deba@2480
   449
	    
deba@2480
   450
	    int yn = node_data[rn].prev;
deba@2480
   451
	    Node ynode = order_list[yn];
deba@2480
   452
	    
deba@2480
   453
	    bool rd;
deba@2480
   454
	    if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
deba@2480
   455
	      rd = true;
deba@2480
   456
	    } else if (!external(ynode, rorder, child_lists, 
deba@2480
   457
				 ancestor_map, low_map)) {
deba@2480
   458
	      rd = false;
deba@2480
   459
	    } else if (pertinent(xnode, embed_edge, merge_roots)) {
deba@2480
   460
	      rd = true;
deba@2480
   461
	    } else {
deba@2480
   462
	      rd = false;
deba@2480
   463
	    }
deba@2480
   464
	    
deba@2480
   465
	    merge_stack.push_back(std::make_pair(rn, rd));
deba@2480
   466
	    
deba@2480
   467
	    pn = rn;
deba@2480
   468
	    n = rd ? xn : yn;	      
deba@2480
   469
	    	    
deba@2480
   470
	  } else if (!external(node, rorder, child_lists,
deba@2480
   471
			       ancestor_map, low_map)) {
deba@2480
   472
	    int nn = (node_data[n].next != pn ? 
deba@2480
   473
		      node_data[n].next : node_data[n].prev);
deba@2480
   474
deba@2480
   475
	    bool nd = n == node_data[nn].prev;
deba@2480
   476
deba@2480
   477
	    if (nd) node_data[nn].prev = pn;
deba@2480
   478
	    else node_data[nn].next = pn; 
deba@2480
   479
deba@2480
   480
	    if (n == node_data[pn].prev) node_data[pn].prev = nn;
deba@2480
   481
	    else node_data[pn].next = nn;
deba@2480
   482
deba@2480
   483
	    node_data[nn].inverted = 
deba@2480
   484
	      (node_data[nn].prev == node_data[nn].next && nd != rd);
deba@2480
   485
deba@2480
   486
	    n = nn;
deba@2480
   487
	  }
deba@2480
   488
	  else break;
deba@2480
   489
	  
deba@2480
   490
	}
deba@2480
   491
deba@2480
   492
	if (!merge_stack.empty() || n == rn) {
deba@2480
   493
	  break;
deba@2480
   494
	}
deba@2480
   495
      }
deba@2480
   496
    }
deba@2480
   497
deba@2480
   498
    void initFace(const Node& node, NodeData& node_data, 
deba@2481
   499
		  const OrderMap& order_map, const OrderList& order_list) {
deba@2480
   500
      int n = order_map[node];
deba@2480
   501
      int rn = n + order_list.size();
deba@2480
   502
      
deba@2480
   503
      node_data[n].next = node_data[n].prev = rn;
deba@2480
   504
      node_data[rn].next = node_data[rn].prev = n;
deba@2480
   505
      
deba@2480
   506
      node_data[n].visited = order_list.size();
deba@2480
   507
      node_data[rn].visited = order_list.size();
deba@2480
   508
      
deba@2480
   509
    }
deba@2480
   510
deba@2480
   511
    bool external(const Node& node, int rorder,
deba@2480
   512
		  ChildLists& child_lists, AncestorMap& ancestor_map, 
deba@2480
   513
		  LowMap& low_map) {
deba@2480
   514
      Node child = child_lists[node].first;
deba@2480
   515
deba@2480
   516
      if (child != INVALID) {
deba@2480
   517
	if (low_map[child] < rorder) return true;
deba@2480
   518
      }
deba@2480
   519
deba@2480
   520
      if (ancestor_map[node] < rorder) return true;
deba@2480
   521
deba@2480
   522
      return false;
deba@2480
   523
    }
deba@2480
   524
deba@2480
   525
    bool pertinent(const Node& node, const EmbedEdge& embed_edge,
deba@2480
   526
		   const MergeRoots& merge_roots) {
deba@2480
   527
      return !merge_roots[node].empty() || embed_edge[node];
deba@2480
   528
    }
deba@2480
   529
deba@2480
   530
  };
deba@2480
   531
deba@2499
   532
  /// \ingroup planar
deba@2480
   533
  ///
deba@2480
   534
  /// \brief Planar embedding of an undirected simple graph
deba@2480
   535
  ///
deba@2480
   536
  /// This class implements the Boyer-Myrvold algorithm for planar
deba@2480
   537
  /// embedding of an undirected graph. The planar embeding is an
deba@2480
   538
  /// ordering of the outgoing edges in each node, which is a possible
deba@2480
   539
  /// configuration to draw the graph in the plane. If there is not
deba@2480
   540
  /// such ordering then the graph contains a \f$ K_5 \f$ (full graph
deba@2480
   541
  /// with 5 nodes) or an \f$ K_{3,3} \f$ (complete bipartite graph on
deba@2480
   542
  /// 3 ANode and 3 BNode) subdivision.
deba@2480
   543
  ///
deba@2480
   544
  /// The current implementation calculates an embedding or an
deba@2480
   545
  /// Kuratowski subdivision if the graph is not planar. The running
deba@2480
   546
  /// time of the algorithm is \f$ O(n) \f$.
deba@2480
   547
  template <typename UGraph>
deba@2480
   548
  class PlanarEmbedding {
deba@2480
   549
  private:
deba@2480
   550
    
deba@2499
   551
    UGRAPH_TYPEDEFS(typename UGraph);
deba@2480
   552
      
deba@2480
   553
    const UGraph& _ugraph;
deba@2480
   554
    typename UGraph::template EdgeMap<Edge> _embedding;
deba@2480
   555
deba@2480
   556
    typename UGraph::template UEdgeMap<bool> _kuratowski;
deba@2480
   557
deba@2480
   558
  private:
deba@2480
   559
deba@2480
   560
    typedef typename UGraph::template NodeMap<Edge> PredMap;
deba@2480
   561
    
deba@2480
   562
    typedef typename UGraph::template UEdgeMap<bool> TreeMap;
deba@2480
   563
deba@2480
   564
    typedef typename UGraph::template NodeMap<int> OrderMap;
deba@2480
   565
    typedef std::vector<Node> OrderList;
deba@2480
   566
deba@2480
   567
    typedef typename UGraph::template NodeMap<int> LowMap;
deba@2480
   568
    typedef typename UGraph::template NodeMap<int> AncestorMap;
deba@2480
   569
deba@2480
   570
    typedef _planarity_bits::NodeDataNode<UGraph> NodeDataNode;
deba@2480
   571
    typedef std::vector<NodeDataNode> NodeData;
deba@2480
   572
    
deba@2480
   573
    typedef _planarity_bits::ChildListNode<UGraph> ChildListNode;
deba@2480
   574
    typedef typename UGraph::template NodeMap<ChildListNode> ChildLists;
deba@2480
   575
deba@2480
   576
    typedef typename UGraph::template NodeMap<std::list<int> > MergeRoots;
deba@2480
   577
 
deba@2480
   578
    typedef typename UGraph::template NodeMap<Edge> EmbedEdge;
deba@2480
   579
deba@2480
   580
    typedef _planarity_bits::EdgeListNode<UGraph> EdgeListNode;
deba@2480
   581
    typedef typename UGraph::template EdgeMap<EdgeListNode> EdgeLists;
deba@2480
   582
deba@2480
   583
    typedef typename UGraph::template NodeMap<bool> FlipMap;
deba@2480
   584
deba@2480
   585
    typedef typename UGraph::template NodeMap<int> TypeMap;
deba@2480
   586
deba@2480
   587
    enum IsolatorNodeType {
deba@2480
   588
      HIGHX = 6, LOWX = 7,
deba@2480
   589
      HIGHY = 8, LOWY = 9,
deba@2480
   590
      ROOT = 10, PERTINENT = 11,
deba@2480
   591
      INTERNAL = 12
deba@2480
   592
    };
deba@2480
   593
deba@2480
   594
  public:
deba@2480
   595
deba@2499
   596
    /// \brief The map for store of embedding
deba@2499
   597
    typedef typename UGraph::template EdgeMap<Edge> EmbeddingMap;
deba@2499
   598
deba@2480
   599
    /// \brief Constructor
deba@2480
   600
    ///
deba@2480
   601
    /// \warining The graph should be simple, i.e. parallel and loop edge
deba@2480
   602
    /// free.
deba@2480
   603
    PlanarEmbedding(const UGraph& ugraph)
deba@2480
   604
      : _ugraph(ugraph), _embedding(_ugraph), _kuratowski(ugraph, false) {}
deba@2480
   605
deba@2480
   606
    /// \brief Runs the algorithm.
deba@2480
   607
    ///
deba@2480
   608
    /// Runs the algorithm.  
deba@2480
   609
    /// \param kuratowski If the parameter is false, then the
deba@2480
   610
    /// algorithm does not calculate the isolate Kuratowski
deba@2480
   611
    /// subdivisions.
deba@2480
   612
    ///\return %True when the graph is planar.
deba@2480
   613
    bool run(bool kuratowski = true) {
deba@2480
   614
      typedef _planarity_bits::PlanarityVisitor<UGraph> Visitor;
deba@2480
   615
deba@2480
   616
      PredMap pred_map(_ugraph, INVALID);
deba@2480
   617
      TreeMap tree_map(_ugraph, false);
deba@2480
   618
deba@2480
   619
      OrderMap order_map(_ugraph, -1);
deba@2480
   620
      OrderList order_list;
deba@2480
   621
deba@2480
   622
      AncestorMap ancestor_map(_ugraph, -1);
deba@2480
   623
      LowMap low_map(_ugraph, -1);
deba@2480
   624
deba@2480
   625
      Visitor visitor(_ugraph, pred_map, tree_map,
deba@2480
   626
		      order_map, order_list, ancestor_map, low_map);
deba@2480
   627
      DfsVisit<UGraph, Visitor> visit(_ugraph, visitor);
deba@2480
   628
      visit.run();
deba@2480
   629
deba@2480
   630
      ChildLists child_lists(_ugraph);
deba@2480
   631
      createChildLists(tree_map, order_map, low_map, child_lists);
deba@2480
   632
deba@2480
   633
      NodeData node_data(2 * order_list.size());
deba@2480
   634
      
deba@2480
   635
      EmbedEdge embed_edge(_ugraph, INVALID);
deba@2480
   636
deba@2480
   637
      MergeRoots merge_roots(_ugraph);
deba@2480
   638
deba@2480
   639
      EdgeLists edge_lists(_ugraph);
deba@2480
   640
deba@2480
   641
      FlipMap flip_map(_ugraph, false);
deba@2480
   642
deba@2480
   643
      for (int i = order_list.size() - 1; i >= 0; --i) {
deba@2480
   644
deba@2480
   645
	Node node = order_list[i];
deba@2480
   646
deba@2480
   647
	node_data[i].first = INVALID;
deba@2480
   648
	
deba@2480
   649
	Node source = node;
deba@2480
   650
	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
deba@2480
   651
	  Node target = _ugraph.target(e);
deba@2480
   652
	  
deba@2480
   653
	  if (order_map[source] < order_map[target] && tree_map[e]) {
deba@2480
   654
	    initFace(target, edge_lists, node_data,
deba@2480
   655
		      pred_map, order_map, order_list);
deba@2480
   656
	  }
deba@2480
   657
	}
deba@2480
   658
	
deba@2480
   659
	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
deba@2480
   660
	  Node target = _ugraph.target(e);
deba@2480
   661
	  
deba@2480
   662
	  if (order_map[source] < order_map[target] && !tree_map[e]) {
deba@2480
   663
	    embed_edge[target] = e;
deba@2480
   664
	    walkUp(target, source, i, pred_map, low_map,
deba@2480
   665
		   order_map, order_list, node_data, merge_roots);
deba@2480
   666
	  }
deba@2480
   667
	}
deba@2480
   668
deba@2480
   669
	for (typename MergeRoots::Value::iterator it = 
deba@2480
   670
	       merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
deba@2480
   671
	  int rn = *it;
deba@2480
   672
	  walkDown(rn, i, node_data, edge_lists, flip_map, order_list, 
deba@2480
   673
		   child_lists, ancestor_map, low_map, embed_edge, merge_roots);
deba@2480
   674
	}
deba@2480
   675
	merge_roots[node].clear();
deba@2480
   676
	
deba@2480
   677
	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
deba@2480
   678
	  Node target = _ugraph.target(e);
deba@2480
   679
	  
deba@2480
   680
	  if (order_map[source] < order_map[target] && !tree_map[e]) {
deba@2480
   681
	    if (embed_edge[target] != INVALID) {
deba@2480
   682
	      if (kuratowski) {
deba@2480
   683
		isolateKuratowski(e, node_data, edge_lists, flip_map,
deba@2480
   684
				  order_map, order_list, pred_map, child_lists,
deba@2480
   685
				  ancestor_map, low_map, 
deba@2480
   686
				  embed_edge, merge_roots);
deba@2480
   687
	      }
deba@2480
   688
	      return false;
deba@2480
   689
	    }
deba@2480
   690
	  }
deba@2480
   691
	}
deba@2480
   692
      }
deba@2480
   693
deba@2480
   694
      for (int i = 0; i < int(order_list.size()); ++i) {
deba@2480
   695
deba@2480
   696
	mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
deba@2480
   697
			    child_lists, edge_lists);
deba@2480
   698
	storeEmbedding(order_list[i], node_data, order_map, pred_map,
deba@2480
   699
		       edge_lists, flip_map);
deba@2480
   700
      }
deba@2480
   701
deba@2480
   702
      return true;
deba@2480
   703
    }
deba@2480
   704
deba@2480
   705
    /// \brief Gives back the successor of an edge
deba@2480
   706
    ///
deba@2480
   707
    /// Gives back the successor of an edge. This function makes
deba@2480
   708
    /// possible to query the cyclic order of the outgoing edges from
deba@2480
   709
    /// a node.
deba@2480
   710
    Edge next(const Edge& edge) const {
deba@2480
   711
      return _embedding[edge];
deba@2480
   712
    }
deba@2480
   713
deba@2499
   714
    /// \brief Gives back the calculated embedding map
deba@2499
   715
    ///
deba@2499
   716
    /// The returned map contains the successor of each edge in the
deba@2499
   717
    /// graph.
deba@2499
   718
    const EmbeddingMap& embedding() const {
deba@2499
   719
      return _embedding;
deba@2499
   720
    }
deba@2499
   721
deba@2480
   722
    /// \brief Gives back true when the undirected edge is in the
deba@2480
   723
    /// kuratowski subdivision
deba@2480
   724
    ///
deba@2480
   725
    /// Gives back true when the undirected edge is in the kuratowski
deba@2480
   726
    /// subdivision
deba@2480
   727
    bool kuratowski(const UEdge& uedge) {
deba@2480
   728
      return _kuratowski[uedge];
deba@2480
   729
    }
deba@2480
   730
deba@2480
   731
  private:
deba@2480
   732
deba@2480
   733
    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
deba@2480
   734
			  const LowMap& low_map, ChildLists& child_lists) {
deba@2480
   735
deba@2480
   736
      for (NodeIt n(_ugraph); n != INVALID; ++n) {
deba@2480
   737
	Node source = n;
deba@2480
   738
	
deba@2480
   739
	std::vector<Node> targets;  
deba@2480
   740
	for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
deba@2480
   741
	  Node target = _ugraph.target(e);
deba@2480
   742
deba@2480
   743
	  if (order_map[source] < order_map[target] && tree_map[e]) {
deba@2480
   744
	    targets.push_back(target);
deba@2480
   745
	  }
deba@2480
   746
	}	
deba@2480
   747
deba@2480
   748
	if (targets.size() == 0) {
deba@2480
   749
	  child_lists[source].first = INVALID;
deba@2480
   750
	} else if (targets.size() == 1) {
deba@2480
   751
	  child_lists[source].first = targets[0];
deba@2480
   752
	  child_lists[targets[0]].prev = INVALID;
deba@2480
   753
	  child_lists[targets[0]].next = INVALID;
deba@2480
   754
	} else {
deba@2480
   755
	  radixSort(targets.begin(), targets.end(), mapFunctor(low_map));
deba@2480
   756
	  for (int i = 1; i < int(targets.size()); ++i) {
deba@2480
   757
	    child_lists[targets[i]].prev = targets[i - 1];
deba@2480
   758
	    child_lists[targets[i - 1]].next = targets[i];
deba@2480
   759
	  }
deba@2480
   760
	  child_lists[targets.back()].next = INVALID; 
deba@2480
   761
	  child_lists[targets.front()].prev = INVALID;
deba@2480
   762
	  child_lists[source].first = targets.front();
deba@2480
   763
	}
deba@2480
   764
      }
deba@2480
   765
    }
deba@2480
   766
deba@2480
   767
    void walkUp(const Node& node, Node root, int rorder,
deba@2480
   768
		const PredMap& pred_map, const LowMap& low_map,
deba@2480
   769
		const OrderMap& order_map, const OrderList& order_list,
deba@2480
   770
		NodeData& node_data, MergeRoots& merge_roots) {
deba@2480
   771
deba@2480
   772
      int na, nb;
deba@2480
   773
      bool da, db;
deba@2480
   774
      
deba@2480
   775
      na = nb = order_map[node];
deba@2480
   776
      da = true; db = false;
deba@2480
   777
      
deba@2480
   778
      while (true) {
deba@2480
   779
	
deba@2480
   780
	if (node_data[na].visited == rorder) break;
deba@2480
   781
	if (node_data[nb].visited == rorder) break;
deba@2480
   782
deba@2480
   783
	node_data[na].visited = rorder;
deba@2480
   784
	node_data[nb].visited = rorder;
deba@2480
   785
deba@2480
   786
	int rn = -1;
deba@2480
   787
deba@2480
   788
	if (na >= int(order_list.size())) {
deba@2480
   789
	  rn = na;
deba@2480
   790
	} else if (nb >= int(order_list.size())) {
deba@2480
   791
	  rn = nb;
deba@2480
   792
	}
deba@2480
   793
deba@2480
   794
	if (rn == -1) {
deba@2480
   795
	  int nn;
deba@2480
   796
	  
deba@2480
   797
	  nn = da ? node_data[na].prev : node_data[na].next;
deba@2480
   798
	  da = node_data[nn].prev != na;
deba@2480
   799
	  na = nn;
deba@2480
   800
	  
deba@2480
   801
	  nn = db ? node_data[nb].prev : node_data[nb].next;
deba@2480
   802
	  db = node_data[nn].prev != nb;
deba@2480
   803
	  nb = nn;
deba@2480
   804
deba@2480
   805
	} else {
deba@2480
   806
deba@2480
   807
	  Node rep = order_list[rn - order_list.size()];
deba@2480
   808
	  Node parent = _ugraph.source(pred_map[rep]);
deba@2480
   809
deba@2480
   810
	  if (low_map[rep] < rorder) {
deba@2480
   811
	    merge_roots[parent].push_back(rn);
deba@2480
   812
	  } else {
deba@2480
   813
	    merge_roots[parent].push_front(rn);
deba@2480
   814
	  }
deba@2480
   815
	  
deba@2480
   816
	  if (parent != root) {  
deba@2480
   817
	    na = nb = order_map[parent];
deba@2480
   818
	    da = true; db = false;
deba@2480
   819
	  } else {
deba@2480
   820
	    break;
deba@2480
   821
	  }
deba@2480
   822
	}	
deba@2480
   823
      }
deba@2480
   824
    }
deba@2480
   825
deba@2480
   826
    void walkDown(int rn, int rorder, NodeData& node_data,
deba@2480
   827
		  EdgeLists& edge_lists, FlipMap& flip_map, 
deba@2480
   828
		  OrderList& order_list, ChildLists& child_lists,
deba@2480
   829
		  AncestorMap& ancestor_map, LowMap& low_map,
deba@2480
   830
		  EmbedEdge& embed_edge, MergeRoots& merge_roots) {
deba@2480
   831
deba@2480
   832
      std::vector<std::pair<int, bool> > merge_stack;
deba@2480
   833
deba@2480
   834
      for (int di = 0; di < 2; ++di) {
deba@2480
   835
	bool rd = di == 0;
deba@2480
   836
	int pn = rn;
deba@2480
   837
	int n = rd ? node_data[rn].next : node_data[rn].prev;
deba@2480
   838
	
deba@2480
   839
	while (n != rn) {
deba@2480
   840
	  
deba@2480
   841
	  Node node = order_list[n];
deba@2480
   842
	  
deba@2480
   843
	  if (embed_edge[node] != INVALID) {
deba@2480
   844
deba@2480
   845
	    // Merging components on the critical path
deba@2480
   846
	    while (!merge_stack.empty()) {
deba@2480
   847
deba@2480
   848
	      // Component root
deba@2480
   849
	      int cn = merge_stack.back().first;
deba@2480
   850
	      bool cd = merge_stack.back().second;
deba@2480
   851
	      merge_stack.pop_back();
deba@2480
   852
deba@2480
   853
	      // Parent of component
deba@2480
   854
	      int dn = merge_stack.back().first;
deba@2480
   855
	      bool dd = merge_stack.back().second;
deba@2480
   856
	      merge_stack.pop_back();
deba@2480
   857
deba@2480
   858
	      Node parent = order_list[dn];
deba@2480
   859
deba@2480
   860
	      // Erasing from merge_roots
deba@2480
   861
	      merge_roots[parent].pop_front();
deba@2480
   862
	      
deba@2480
   863
	      Node child = order_list[cn - order_list.size()];
deba@2480
   864
deba@2480
   865
	      // Erasing from child_lists
deba@2480
   866
	      if (child_lists[child].prev != INVALID) {
deba@2480
   867
		child_lists[child_lists[child].prev].next =
deba@2480
   868
		  child_lists[child].next;
deba@2480
   869
	      } else {
deba@2480
   870
		child_lists[parent].first = child_lists[child].next;
deba@2480
   871
	      }
deba@2480
   872
	      
deba@2480
   873
	      if (child_lists[child].next != INVALID) {
deba@2480
   874
		child_lists[child_lists[child].next].prev =
deba@2480
   875
		  child_lists[child].prev;
deba@2480
   876
	      }
deba@2480
   877
deba@2480
   878
	      // Merging edges + flipping
deba@2480
   879
	      Edge de = node_data[dn].first;
deba@2480
   880
	      Edge ce = node_data[cn].first;
deba@2480
   881
deba@2480
   882
	      flip_map[order_list[cn - order_list.size()]] = cd != dd;
deba@2480
   883
	      if (cd != dd) {
deba@2480
   884
		std::swap(edge_lists[ce].prev, edge_lists[ce].next);
deba@2480
   885
		ce = edge_lists[ce].prev;
deba@2480
   886
		std::swap(edge_lists[ce].prev, edge_lists[ce].next);
deba@2480
   887
	      }
deba@2480
   888
deba@2480
   889
	      {
deba@2480
   890
		Edge dne = edge_lists[de].next; 
deba@2480
   891
		Edge cne = edge_lists[ce].next; 
deba@2480
   892
deba@2480
   893
		edge_lists[de].next = cne;
deba@2480
   894
		edge_lists[ce].next = dne;
deba@2480
   895
	      
deba@2480
   896
		edge_lists[dne].prev = ce;
deba@2480
   897
		edge_lists[cne].prev = de;
deba@2480
   898
	      }
deba@2480
   899
	      	      
deba@2480
   900
	      if (dd) {
deba@2480
   901
		node_data[dn].first = ce;
deba@2480
   902
	      }
deba@2480
   903
	      
deba@2480
   904
	      // Merging external faces
deba@2480
   905
	      {
deba@2480
   906
		int en = cn;
deba@2480
   907
		cn = cd ? node_data[cn].prev : node_data[cn].next;
deba@2480
   908
		cd = node_data[cn].next == en;
deba@2480
   909
deba@2480
   910
 		if (node_data[cn].prev == node_data[cn].next && 
deba@2480
   911
		    node_data[cn].inverted) {
deba@2480
   912
 		  cd = !cd;
deba@2480
   913
 		}
deba@2480
   914
	      }
deba@2480
   915
deba@2480
   916
	      if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
deba@2480
   917
	      if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
deba@2480
   918
deba@2480
   919
	    }
deba@2480
   920
deba@2480
   921
	    bool d = pn == node_data[n].prev;
deba@2480
   922
deba@2480
   923
	    if (node_data[n].prev == node_data[n].next && 
deba@2480
   924
		node_data[n].inverted) {
deba@2480
   925
	      d = !d;
deba@2480
   926
	    }
deba@2480
   927
deba@2480
   928
	    // Add new edge
deba@2480
   929
	    {
deba@2480
   930
	      Edge edge = embed_edge[node];
deba@2480
   931
	      Edge re = node_data[rn].first;
deba@2480
   932
deba@2480
   933
	      edge_lists[edge_lists[re].next].prev = edge;
deba@2480
   934
	      edge_lists[edge].next = edge_lists[re].next;
deba@2480
   935
	      edge_lists[edge].prev = re;
deba@2480
   936
	      edge_lists[re].next = edge;
deba@2480
   937
deba@2480
   938
	      if (!rd) {
deba@2480
   939
		node_data[rn].first = edge;
deba@2480
   940
	      }
deba@2480
   941
deba@2480
   942
	      Edge rev = _ugraph.oppositeEdge(edge);
deba@2480
   943
	      Edge e = node_data[n].first;
deba@2480
   944
deba@2480
   945
	      edge_lists[edge_lists[e].next].prev = rev;
deba@2480
   946
	      edge_lists[rev].next = edge_lists[e].next;
deba@2480
   947
	      edge_lists[rev].prev = e;
deba@2480
   948
	      edge_lists[e].next = rev;
deba@2480
   949
deba@2480
   950
	      if (d) {
deba@2480
   951
		node_data[n].first = rev;
deba@2480
   952
	      }
deba@2480
   953
	      
deba@2480
   954
	    }
deba@2480
   955
deba@2480
   956
	    // Embedding edge into external face
deba@2480
   957
	    if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
deba@2480
   958
	    if (d) node_data[n].prev = rn; else node_data[n].next = rn;
deba@2480
   959
	    pn = rn;
deba@2480
   960
deba@2480
   961
	    embed_edge[order_list[n]] = INVALID;
deba@2480
   962
	  }
deba@2480
   963
deba@2480
   964
	  if (!merge_roots[node].empty()) {
deba@2480
   965
deba@2480
   966
	    bool d = pn == node_data[n].prev;
deba@2480
   967
	    if (node_data[n].prev == node_data[n].next && 
deba@2480
   968
		node_data[n].inverted) {
deba@2480
   969
	      d = !d;
deba@2480
   970
	    }
deba@2480
   971
deba@2480
   972
	    merge_stack.push_back(std::make_pair(n, d));
deba@2480
   973
deba@2480
   974
	    int rn = merge_roots[node].front();
deba@2480
   975
	    
deba@2480
   976
	    int xn = node_data[rn].next;
deba@2480
   977
	    Node xnode = order_list[xn];
deba@2480
   978
	    
deba@2480
   979
	    int yn = node_data[rn].prev;
deba@2480
   980
	    Node ynode = order_list[yn];
deba@2480
   981
	    
deba@2480
   982
	    bool rd;
deba@2480
   983
	    if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
deba@2480
   984
	      rd = true;
deba@2480
   985
	    } else if (!external(ynode, rorder, child_lists, 
deba@2480
   986
				 ancestor_map, low_map)) {
deba@2480
   987
	      rd = false;
deba@2480
   988
	    } else if (pertinent(xnode, embed_edge, merge_roots)) {
deba@2480
   989
	      rd = true;
deba@2480
   990
	    } else {
deba@2480
   991
	      rd = false;
deba@2480
   992
	    }
deba@2480
   993
	    
deba@2480
   994
	    merge_stack.push_back(std::make_pair(rn, rd));
deba@2480
   995
	    
deba@2480
   996
	    pn = rn;
deba@2480
   997
	    n = rd ? xn : yn;	      
deba@2480
   998
	    	    
deba@2480
   999
	  } else if (!external(node, rorder, child_lists,
deba@2480
  1000
			       ancestor_map, low_map)) {
deba@2480
  1001
	    int nn = (node_data[n].next != pn ? 
deba@2480
  1002
		      node_data[n].next : node_data[n].prev);
deba@2480
  1003
deba@2480
  1004
	    bool nd = n == node_data[nn].prev;
deba@2480
  1005
deba@2480
  1006
	    if (nd) node_data[nn].prev = pn;
deba@2480
  1007
	    else node_data[nn].next = pn; 
deba@2480
  1008
deba@2480
  1009
	    if (n == node_data[pn].prev) node_data[pn].prev = nn;
deba@2480
  1010
	    else node_data[pn].next = nn;
deba@2480
  1011
deba@2480
  1012
	    node_data[nn].inverted = 
deba@2480
  1013
	      (node_data[nn].prev == node_data[nn].next && nd != rd);
deba@2480
  1014
deba@2480
  1015
	    n = nn;
deba@2480
  1016
	  }
deba@2480
  1017
	  else break;
deba@2480
  1018
	  
deba@2480
  1019
	}
deba@2480
  1020
deba@2480
  1021
	if (!merge_stack.empty() || n == rn) {
deba@2480
  1022
	  break;
deba@2480
  1023
	}
deba@2480
  1024
      }
deba@2480
  1025
    }
deba@2480
  1026
deba@2480
  1027
    void initFace(const Node& node, EdgeLists& edge_lists,
deba@2480
  1028
		   NodeData& node_data, const PredMap& pred_map,
deba@2480
  1029
		   const OrderMap& order_map, const OrderList& order_list) {
deba@2480
  1030
      int n = order_map[node];
deba@2480
  1031
      int rn = n + order_list.size();
deba@2480
  1032
      
deba@2480
  1033
      node_data[n].next = node_data[n].prev = rn;
deba@2480
  1034
      node_data[rn].next = node_data[rn].prev = n;
deba@2480
  1035
      
deba@2480
  1036
      node_data[n].visited = order_list.size();
deba@2480
  1037
      node_data[rn].visited = order_list.size();
deba@2480
  1038
deba@2480
  1039
      node_data[n].inverted = false;
deba@2480
  1040
      node_data[rn].inverted = false;
deba@2480
  1041
deba@2480
  1042
      Edge edge = pred_map[node];
deba@2480
  1043
      Edge rev = _ugraph.oppositeEdge(edge);
deba@2480
  1044
deba@2480
  1045
      node_data[rn].first = edge;
deba@2480
  1046
      node_data[n].first = rev;
deba@2480
  1047
deba@2480
  1048
      edge_lists[edge].prev = edge;
deba@2480
  1049
      edge_lists[edge].next = edge;
deba@2480
  1050
deba@2480
  1051
      edge_lists[rev].prev = rev;
deba@2480
  1052
      edge_lists[rev].next = rev;
deba@2480
  1053
deba@2480
  1054
    }
deba@2480
  1055
deba@2480
  1056
    void mergeRemainingFaces(const Node& node, NodeData& node_data,
deba@2480
  1057
			     OrderList& order_list, OrderMap& order_map,
deba@2480
  1058
			     ChildLists& child_lists, EdgeLists& edge_lists) {
deba@2480
  1059
      while (child_lists[node].first != INVALID) {
deba@2480
  1060
	int dd = order_map[node];
deba@2480
  1061
	Node child = child_lists[node].first; 
deba@2480
  1062
	int cd = order_map[child] + order_list.size();
deba@2480
  1063
	child_lists[node].first = child_lists[child].next;
deba@2480
  1064
deba@2480
  1065
	Edge de = node_data[dd].first;
deba@2480
  1066
	Edge ce = node_data[cd].first;
deba@2480
  1067
deba@2480
  1068
	if (de != INVALID) {
deba@2480
  1069
	  Edge dne = edge_lists[de].next; 
deba@2480
  1070
	  Edge cne = edge_lists[ce].next; 
deba@2480
  1071
	  
deba@2480
  1072
	  edge_lists[de].next = cne;
deba@2480
  1073
	  edge_lists[ce].next = dne;
deba@2480
  1074
	  
deba@2480
  1075
	  edge_lists[dne].prev = ce;
deba@2480
  1076
	  edge_lists[cne].prev = de;
deba@2480
  1077
	}
deba@2480
  1078
	
deba@2480
  1079
	node_data[dd].first = ce;
deba@2480
  1080
deba@2480
  1081
      }
deba@2480
  1082
    }
deba@2480
  1083
deba@2480
  1084
    void storeEmbedding(const Node& node, NodeData& node_data,
deba@2480
  1085
			OrderMap& order_map, PredMap& pred_map,
deba@2480
  1086
			EdgeLists& edge_lists, FlipMap& flip_map) {
deba@2480
  1087
deba@2480
  1088
      if (node_data[order_map[node]].first == INVALID) return;
deba@2480
  1089
deba@2480
  1090
      if (pred_map[node] != INVALID) {
deba@2480
  1091
	Node source = _ugraph.source(pred_map[node]);
deba@2480
  1092
	flip_map[node] = flip_map[node] != flip_map[source];
deba@2480
  1093
      }
deba@2480
  1094
      
deba@2480
  1095
      Edge first = node_data[order_map[node]].first;
deba@2480
  1096
      Edge prev = first;
deba@2480
  1097
deba@2480
  1098
      Edge edge = flip_map[node] ?
deba@2480
  1099
	edge_lists[prev].prev : edge_lists[prev].next;
deba@2480
  1100
deba@2480
  1101
      _embedding[prev] = edge;
deba@2480
  1102
      
deba@2480
  1103
      while (edge != first) {
deba@2480
  1104
	Edge next = edge_lists[edge].prev == prev ?
deba@2480
  1105
	  edge_lists[edge].next : edge_lists[edge].prev;
deba@2480
  1106
	prev = edge; edge = next;
deba@2480
  1107
	_embedding[prev] = edge;
deba@2480
  1108
      }
deba@2480
  1109
    }
deba@2480
  1110
deba@2480
  1111
deba@2480
  1112
    bool external(const Node& node, int rorder,
deba@2480
  1113
		  ChildLists& child_lists, AncestorMap& ancestor_map, 
deba@2480
  1114
		  LowMap& low_map) {
deba@2480
  1115
      Node child = child_lists[node].first;
deba@2480
  1116
deba@2480
  1117
      if (child != INVALID) {
deba@2480
  1118
	if (low_map[child] < rorder) return true;
deba@2480
  1119
      }
deba@2480
  1120
deba@2480
  1121
      if (ancestor_map[node] < rorder) return true;
deba@2480
  1122
deba@2480
  1123
      return false;
deba@2480
  1124
    }
deba@2480
  1125
deba@2480
  1126
    bool pertinent(const Node& node, const EmbedEdge& embed_edge,
deba@2480
  1127
		   const MergeRoots& merge_roots) {
deba@2480
  1128
      return !merge_roots[node].empty() || embed_edge[node] != INVALID;
deba@2480
  1129
    }
deba@2480
  1130
deba@2480
  1131
    int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
deba@2480
  1132
		 AncestorMap& ancestor_map, LowMap& low_map) {
deba@2480
  1133
      int low_point;
deba@2480
  1134
deba@2480
  1135
      Node child = child_lists[node].first;
deba@2480
  1136
deba@2480
  1137
      if (child != INVALID) {
deba@2480
  1138
	low_point = low_map[child];
deba@2480
  1139
      } else {
deba@2480
  1140
	low_point = order_map[node];
deba@2480
  1141
      }
deba@2480
  1142
deba@2480
  1143
      if (low_point > ancestor_map[node]) {
deba@2480
  1144
	low_point = ancestor_map[node];
deba@2480
  1145
      }
deba@2480
  1146
deba@2480
  1147
      return low_point;
deba@2480
  1148
    }
deba@2480
  1149
deba@2480
  1150
    int findComponentRoot(Node root, Node node, ChildLists& child_lists, 
deba@2480
  1151
			  OrderMap& order_map, OrderList& order_list) {
deba@2480
  1152
deba@2480
  1153
      int order = order_map[root];
deba@2480
  1154
      int norder = order_map[node];
deba@2480
  1155
deba@2480
  1156
      Node child = child_lists[root].first;
deba@2480
  1157
      while (child != INVALID) {
deba@2480
  1158
	int corder = order_map[child];
deba@2480
  1159
	if (corder > order && corder < norder) {
deba@2480
  1160
	  order = corder;
deba@2480
  1161
	}
deba@2480
  1162
	child = child_lists[child].next;
deba@2480
  1163
      }
deba@2480
  1164
      return order + order_list.size();
deba@2480
  1165
    }
deba@2480
  1166
deba@2480
  1167
    Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
deba@2480
  1168
		       EmbedEdge& embed_edge, MergeRoots& merge_roots) {
deba@2480
  1169
      Node wnode =_ugraph.target(node_data[order_map[node]].first);
deba@2480
  1170
      while (!pertinent(wnode, embed_edge, merge_roots)) {
deba@2480
  1171
	wnode = _ugraph.target(node_data[order_map[wnode]].first);
deba@2480
  1172
      }
deba@2480
  1173
      return wnode;
deba@2480
  1174
    }
deba@2480
  1175
deba@2480
  1176
deba@2480
  1177
    Node findExternal(Node node, int rorder, OrderMap& order_map, 
deba@2480
  1178
		      ChildLists& child_lists, AncestorMap& ancestor_map,
deba@2480
  1179
		      LowMap& low_map, NodeData& node_data) {
deba@2480
  1180
      Node wnode =_ugraph.target(node_data[order_map[node]].first);
deba@2480
  1181
      while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
deba@2480
  1182
	wnode = _ugraph.target(node_data[order_map[wnode]].first);
deba@2480
  1183
      }
deba@2480
  1184
      return wnode;
deba@2480
  1185
    }
deba@2480
  1186
deba@2480
  1187
    void markCommonPath(Node node, int rorder, Node& wnode, Node& znode, 
deba@2480
  1188
			OrderList& order_list, OrderMap& order_map, 
deba@2480
  1189
			NodeData& node_data, EdgeLists& edge_lists, 
deba@2480
  1190
			EmbedEdge& embed_edge, MergeRoots& merge_roots, 
deba@2480
  1191
			ChildLists& child_lists, AncestorMap& ancestor_map, 
deba@2480
  1192
			LowMap& low_map) {
deba@2480
  1193
      
deba@2480
  1194
      Node cnode = node;
deba@2480
  1195
      Node pred = INVALID;
deba@2480
  1196
      
deba@2480
  1197
      while (true) {
deba@2480
  1198
deba@2480
  1199
	bool pert = pertinent(cnode, embed_edge, merge_roots);
deba@2480
  1200
	bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
deba@2480
  1201
deba@2480
  1202
	if (pert && ext) {
deba@2480
  1203
	  if (!merge_roots[cnode].empty()) {
deba@2480
  1204
	    int cn = merge_roots[cnode].back();
deba@2480
  1205
	    
deba@2480
  1206
	    if (low_map[order_list[cn - order_list.size()]] < rorder) {
deba@2480
  1207
	      Edge edge = node_data[cn].first;
deba@2480
  1208
	      _kuratowski.set(edge, true);
deba@2480
  1209
	      
deba@2480
  1210
	      pred = cnode;
deba@2480
  1211
	      cnode = _ugraph.target(edge);
deba@2480
  1212
	    
deba@2480
  1213
	      continue;
deba@2480
  1214
	    }
deba@2480
  1215
	  }
deba@2480
  1216
	  wnode = znode = cnode;
deba@2480
  1217
	  return;
deba@2480
  1218
deba@2480
  1219
	} else if (pert) {
deba@2480
  1220
	  wnode = cnode;
deba@2480
  1221
	  
deba@2480
  1222
	  while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
deba@2480
  1223
	    Edge edge = node_data[order_map[cnode]].first;
deba@2480
  1224
	  
deba@2480
  1225
	    if (_ugraph.target(edge) == pred) {
deba@2480
  1226
	      edge = edge_lists[edge].next;
deba@2480
  1227
	    }
deba@2480
  1228
	    _kuratowski.set(edge, true);
deba@2480
  1229
	    
deba@2480
  1230
	    Node next = _ugraph.target(edge);
deba@2480
  1231
	    pred = cnode; cnode = next;
deba@2480
  1232
	  }
deba@2480
  1233
	  
deba@2480
  1234
	  znode = cnode;
deba@2480
  1235
	  return;
deba@2480
  1236
deba@2480
  1237
	} else if (ext) {
deba@2480
  1238
	  znode = cnode;
deba@2480
  1239
	  
deba@2480
  1240
	  while (!pertinent(cnode, embed_edge, merge_roots)) {
deba@2480
  1241
	    Edge edge = node_data[order_map[cnode]].first;
deba@2480
  1242
	  
deba@2480
  1243
	    if (_ugraph.target(edge) == pred) {
deba@2480
  1244
	      edge = edge_lists[edge].next;
deba@2480
  1245
	    }
deba@2480
  1246
	    _kuratowski.set(edge, true);
deba@2480
  1247
	    
deba@2480
  1248
	    Node next = _ugraph.target(edge);
deba@2480
  1249
	    pred = cnode; cnode = next;
deba@2480
  1250
	  }
deba@2480
  1251
	  
deba@2480
  1252
	  wnode = cnode;
deba@2480
  1253
	  return;
deba@2480
  1254
	  
deba@2480
  1255
	} else {
deba@2480
  1256
	  Edge edge = node_data[order_map[cnode]].first;
deba@2480
  1257
	  
deba@2480
  1258
	  if (_ugraph.target(edge) == pred) {
deba@2480
  1259
	    edge = edge_lists[edge].next;
deba@2480
  1260
	  }
deba@2480
  1261
	  _kuratowski.set(edge, true);
deba@2480
  1262
deba@2480
  1263
	  Node next = _ugraph.target(edge);
deba@2480
  1264
	  pred = cnode; cnode = next;
deba@2480
  1265
	}
deba@2480
  1266
	
deba@2480
  1267
      }
deba@2480
  1268
deba@2480
  1269
    }
deba@2480
  1270
deba@2480
  1271
    void orientComponent(Node root, int rn, OrderMap& order_map,
deba@2480
  1272
			 PredMap& pred_map, NodeData& node_data, 
deba@2480
  1273
			 EdgeLists& edge_lists, FlipMap& flip_map, 
deba@2480
  1274
			 TypeMap& type_map) {
deba@2480
  1275
      node_data[order_map[root]].first = node_data[rn].first;
deba@2480
  1276
      type_map[root] = 1;
deba@2480
  1277
deba@2480
  1278
      std::vector<Node> st, qu;
deba@2480
  1279
deba@2480
  1280
      st.push_back(root);
deba@2480
  1281
      while (!st.empty()) {
deba@2480
  1282
	Node node = st.back();
deba@2480
  1283
	st.pop_back();
deba@2480
  1284
	qu.push_back(node);
deba@2480
  1285
	
deba@2480
  1286
	Edge edge = node_data[order_map[node]].first;
deba@2480
  1287
	
deba@2480
  1288
	if (type_map[_ugraph.target(edge)] == 0) {
deba@2480
  1289
	  st.push_back(_ugraph.target(edge));
deba@2480
  1290
	  type_map[_ugraph.target(edge)] = 1;
deba@2480
  1291
	} 
deba@2480
  1292
	
deba@2480
  1293
	Edge last = edge, pred = edge;
deba@2480
  1294
	edge = edge_lists[edge].next;
deba@2480
  1295
	while (edge != last) {
deba@2480
  1296
deba@2480
  1297
	  if (type_map[_ugraph.target(edge)] == 0) {
deba@2480
  1298
	    st.push_back(_ugraph.target(edge));
deba@2480
  1299
	    type_map[_ugraph.target(edge)] = 1;
deba@2480
  1300
	  } 
deba@2480
  1301
	  
deba@2480
  1302
	  Edge next = edge_lists[edge].next != pred ? 
deba@2480
  1303
	    edge_lists[edge].next : edge_lists[edge].prev;
deba@2480
  1304
	  pred = edge; edge = next;
deba@2480
  1305
	}
deba@2480
  1306
deba@2480
  1307
      }
deba@2480
  1308
deba@2480
  1309
      type_map[root] = 2;
deba@2480
  1310
      flip_map[root] = false;
deba@2480
  1311
deba@2480
  1312
      for (int i = 1; i < int(qu.size()); ++i) {
deba@2480
  1313
deba@2480
  1314
	Node node = qu[i];
deba@2480
  1315
deba@2480
  1316
	while (type_map[node] != 2) {
deba@2480
  1317
	  st.push_back(node);
deba@2480
  1318
	  type_map[node] = 2;
deba@2480
  1319
	  node = _ugraph.source(pred_map[node]);
deba@2480
  1320
	}
deba@2480
  1321
deba@2480
  1322
	bool flip = flip_map[node];
deba@2480
  1323
deba@2480
  1324
	while (!st.empty()) {
deba@2480
  1325
	  node = st.back();
deba@2480
  1326
	  st.pop_back();
deba@2480
  1327
	  
deba@2480
  1328
	  flip_map[node] = flip != flip_map[node];
deba@2480
  1329
	  flip = flip_map[node];
deba@2480
  1330
deba@2480
  1331
	  if (flip) {
deba@2480
  1332
	    Edge edge = node_data[order_map[node]].first;
deba@2480
  1333
	    std::swap(edge_lists[edge].prev, edge_lists[edge].next);
deba@2480
  1334
	    edge = edge_lists[edge].prev;
deba@2480
  1335
	    std::swap(edge_lists[edge].prev, edge_lists[edge].next);
deba@2480
  1336
	    node_data[order_map[node]].first = edge;
deba@2480
  1337
	  }
deba@2480
  1338
	}
deba@2480
  1339
      }
deba@2480
  1340
deba@2480
  1341
      for (int i = 0; i < int(qu.size()); ++i) {
deba@2480
  1342
deba@2480
  1343
	Edge edge = node_data[order_map[qu[i]]].first;
deba@2480
  1344
	Edge last = edge, pred = edge;
deba@2480
  1345
deba@2480
  1346
	edge = edge_lists[edge].next;
deba@2480
  1347
	while (edge != last) {
deba@2480
  1348
deba@2480
  1349
	  if (edge_lists[edge].next == pred) {
deba@2480
  1350
	    std::swap(edge_lists[edge].next, edge_lists[edge].prev);
deba@2480
  1351
	  } 
deba@2480
  1352
	  pred = edge; edge = edge_lists[edge].next;
deba@2480
  1353
	}
deba@2480
  1354
	
deba@2480
  1355
      }
deba@2480
  1356
    }
deba@2480
  1357
deba@2480
  1358
    void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
deba@2480
  1359
		      OrderMap& order_map, NodeData& node_data, 
deba@2480
  1360
		      TypeMap& type_map) {
deba@2480
  1361
      Node node = _ugraph.target(node_data[order_map[root]].first);
deba@2480
  1362
deba@2480
  1363
      while (node != ynode) {
deba@2480
  1364
	type_map[node] = HIGHY;
deba@2480
  1365
	node = _ugraph.target(node_data[order_map[node]].first);
deba@2480
  1366
      }
deba@2480
  1367
deba@2480
  1368
      while (node != wnode) {
deba@2480
  1369
	type_map[node] = LOWY;
deba@2480
  1370
	node = _ugraph.target(node_data[order_map[node]].first);
deba@2480
  1371
      }
deba@2480
  1372
      
deba@2480
  1373
      node = _ugraph.target(node_data[order_map[wnode]].first);
deba@2480
  1374
      
deba@2480
  1375
      while (node != xnode) {
deba@2480
  1376
	type_map[node] = LOWX;
deba@2480
  1377
	node = _ugraph.target(node_data[order_map[node]].first);
deba@2480
  1378
      }
deba@2480
  1379
      type_map[node] = LOWX;
deba@2480
  1380
deba@2480
  1381
      node = _ugraph.target(node_data[order_map[xnode]].first);
deba@2480
  1382
      while (node != root) {
deba@2480
  1383
	type_map[node] = HIGHX;
deba@2480
  1384
	node = _ugraph.target(node_data[order_map[node]].first);
deba@2480
  1385
      }
deba@2480
  1386
deba@2480
  1387
      type_map[wnode] = PERTINENT;
deba@2480
  1388
      type_map[root] = ROOT;
deba@2480
  1389
    }
deba@2480
  1390
deba@2480
  1391
    void findInternalPath(std::vector<Edge>& ipath,
deba@2480
  1392
			  Node wnode, Node root, TypeMap& type_map, 
deba@2480
  1393
			  OrderMap& order_map, NodeData& node_data, 
deba@2480
  1394
			  EdgeLists& edge_lists) {
deba@2480
  1395
      std::vector<Edge> st;
deba@2480
  1396
deba@2480
  1397
      Node node = wnode;
deba@2480
  1398
      
deba@2480
  1399
      while (node != root) {
deba@2480
  1400
	Edge edge = edge_lists[node_data[order_map[node]].first].next;
deba@2480
  1401
	st.push_back(edge);
deba@2480
  1402
	node = _ugraph.target(edge);
deba@2480
  1403
      }
deba@2480
  1404
      
deba@2480
  1405
      while (true) {
deba@2480
  1406
	Edge edge = st.back();
deba@2480
  1407
	if (type_map[_ugraph.target(edge)] == LOWX ||
deba@2480
  1408
	    type_map[_ugraph.target(edge)] == HIGHX) {
deba@2480
  1409
	  break;
deba@2480
  1410
	}
deba@2480
  1411
	if (type_map[_ugraph.target(edge)] == 2) {
deba@2480
  1412
	  type_map[_ugraph.target(edge)] = 3;
deba@2480
  1413
	  
deba@2480
  1414
	  edge = edge_lists[_ugraph.oppositeEdge(edge)].next;
deba@2480
  1415
	  st.push_back(edge);
deba@2480
  1416
	} else {
deba@2480
  1417
	  st.pop_back();
deba@2480
  1418
	  edge = edge_lists[edge].next;
deba@2480
  1419
	  
deba@2480
  1420
	  while (_ugraph.oppositeEdge(edge) == st.back()) {
deba@2480
  1421
	    edge = st.back();
deba@2480
  1422
	    st.pop_back();
deba@2480
  1423
	    edge = edge_lists[edge].next;
deba@2480
  1424
	  }
deba@2480
  1425
	  st.push_back(edge);
deba@2480
  1426
	}
deba@2480
  1427
      }
deba@2480
  1428
      
deba@2480
  1429
      for (int i = 0; i < int(st.size()); ++i) {
deba@2480
  1430
	if (type_map[_ugraph.target(st[i])] != LOWY &&
deba@2480
  1431
	    type_map[_ugraph.target(st[i])] != HIGHY) {
deba@2480
  1432
	  for (; i < int(st.size()); ++i) {
deba@2480
  1433
	    ipath.push_back(st[i]);
deba@2480
  1434
	  }
deba@2480
  1435
	}
deba@2480
  1436
      }
deba@2480
  1437
    }
deba@2480
  1438
deba@2480
  1439
    void setInternalFlags(std::vector<Edge>& ipath, TypeMap& type_map) {
deba@2480
  1440
      for (int i = 1; i < int(ipath.size()); ++i) {
deba@2480
  1441
	type_map[_ugraph.source(ipath[i])] = INTERNAL;
deba@2480
  1442
      }
deba@2480
  1443
    }
deba@2480
  1444
deba@2480
  1445
    void findPilePath(std::vector<Edge>& ppath,
deba@2480
  1446
		      Node root, TypeMap& type_map, OrderMap& order_map, 
deba@2480
  1447
		      NodeData& node_data, EdgeLists& edge_lists) {
deba@2480
  1448
      std::vector<Edge> st;
deba@2480
  1449
deba@2480
  1450
      st.push_back(_ugraph.oppositeEdge(node_data[order_map[root]].first));
deba@2480
  1451
      st.push_back(node_data[order_map[root]].first);
deba@2480
  1452
      
deba@2480
  1453
      while (st.size() > 1) {
deba@2480
  1454
	Edge edge = st.back();
deba@2480
  1455
	if (type_map[_ugraph.target(edge)] == INTERNAL) {
deba@2480
  1456
	  break;
deba@2480
  1457
	}
deba@2480
  1458
	if (type_map[_ugraph.target(edge)] == 3) {
deba@2480
  1459
	  type_map[_ugraph.target(edge)] = 4;
deba@2480
  1460
	  
deba@2480
  1461
	  edge = edge_lists[_ugraph.oppositeEdge(edge)].next;
deba@2480
  1462
	  st.push_back(edge);
deba@2480
  1463
	} else {
deba@2480
  1464
	  st.pop_back();
deba@2480
  1465
	  edge = edge_lists[edge].next;
deba@2480
  1466
	  
deba@2480
  1467
	  while (!st.empty() && _ugraph.oppositeEdge(edge) == st.back()) {
deba@2480
  1468
	    edge = st.back();
deba@2480
  1469
	    st.pop_back();
deba@2480
  1470
	    edge = edge_lists[edge].next;
deba@2480
  1471
	  }
deba@2480
  1472
	  st.push_back(edge);
deba@2480
  1473
	}
deba@2480
  1474
      }
deba@2480
  1475
      
deba@2480
  1476
      for (int i = 1; i < int(st.size()); ++i) {
deba@2480
  1477
	ppath.push_back(st[i]);
deba@2480
  1478
      }
deba@2480
  1479
    }
deba@2480
  1480
deba@2480
  1481
deba@2480
  1482
    int markExternalPath(Node node, OrderMap& order_map,
deba@2480
  1483
			 ChildLists& child_lists, PredMap& pred_map,
deba@2480
  1484
			 AncestorMap& ancestor_map, LowMap& low_map) {
deba@2480
  1485
      int lp = lowPoint(node, order_map, child_lists,
deba@2480
  1486
			ancestor_map, low_map);
deba@2480
  1487
      
deba@2480
  1488
      if (ancestor_map[node] != lp) {
deba@2480
  1489
	node = child_lists[node].first;
deba@2480
  1490
	_kuratowski[pred_map[node]] = true;
deba@2480
  1491
deba@2480
  1492
	while (ancestor_map[node] != lp) {
deba@2480
  1493
	  for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
deba@2480
  1494
	    Node tnode = _ugraph.target(e); 
deba@2480
  1495
	    if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
deba@2480
  1496
	      node = tnode;
deba@2480
  1497
	      _kuratowski[e] = true;
deba@2480
  1498
	      break;
deba@2480
  1499
	    }
deba@2480
  1500
	  }
deba@2480
  1501
	}
deba@2480
  1502
      }
deba@2480
  1503
deba@2480
  1504
      for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
deba@2480
  1505
	if (order_map[_ugraph.target(e)] == lp) {
deba@2480
  1506
	  _kuratowski[e] = true;
deba@2480
  1507
	  break;
deba@2480
  1508
	}
deba@2480
  1509
      }
deba@2480
  1510
      
deba@2480
  1511
      return lp;
deba@2480
  1512
    }
deba@2480
  1513
deba@2480
  1514
    void markPertinentPath(Node node, OrderMap& order_map, 
deba@2480
  1515
			   NodeData& node_data, EdgeLists& edge_lists,
deba@2480
  1516
			   EmbedEdge& embed_edge, MergeRoots& merge_roots) {
deba@2480
  1517
      while (embed_edge[node] == INVALID) {
deba@2480
  1518
	int n = merge_roots[node].front();
deba@2480
  1519
	Edge edge = node_data[n].first;
deba@2480
  1520
deba@2480
  1521
	_kuratowski.set(edge, true);
deba@2480
  1522
	
deba@2480
  1523
	Node pred = node;
deba@2480
  1524
	node = _ugraph.target(edge);
deba@2480
  1525
	while (!pertinent(node, embed_edge, merge_roots)) {
deba@2480
  1526
	  edge = node_data[order_map[node]].first;
deba@2480
  1527
	  if (_ugraph.target(edge) == pred) {
deba@2480
  1528
	    edge = edge_lists[edge].next;
deba@2480
  1529
	  }
deba@2480
  1530
	  _kuratowski.set(edge, true);
deba@2480
  1531
	  pred = node;
deba@2480
  1532
	  node = _ugraph.target(edge);
deba@2480
  1533
	}
deba@2480
  1534
      }
deba@2480
  1535
      _kuratowski.set(embed_edge[node], true);
deba@2480
  1536
    } 
deba@2480
  1537
deba@2480
  1538
    void markPredPath(Node node, Node snode, PredMap& pred_map) {
deba@2480
  1539
      while (node != snode) {
deba@2480
  1540
	_kuratowski.set(pred_map[node], true);
deba@2480
  1541
	node = _ugraph.source(pred_map[node]);
deba@2480
  1542
      }
deba@2480
  1543
    }
deba@2480
  1544
deba@2480
  1545
    void markFacePath(Node ynode, Node xnode, 
deba@2480
  1546
		      OrderMap& order_map, NodeData& node_data) {
deba@2480
  1547
      Edge edge = node_data[order_map[ynode]].first;
deba@2480
  1548
      Node node = _ugraph.target(edge);
deba@2480
  1549
      _kuratowski.set(edge, true);
deba@2480
  1550
	
deba@2480
  1551
      while (node != xnode) {
deba@2480
  1552
	edge = node_data[order_map[node]].first;
deba@2480
  1553
	_kuratowski.set(edge, true);
deba@2480
  1554
	node = _ugraph.target(edge);
deba@2480
  1555
      }
deba@2480
  1556
    }
deba@2480
  1557
deba@2480
  1558
    void markInternalPath(std::vector<Edge>& path) {
deba@2480
  1559
      for (int i = 0; i < int(path.size()); ++i) {
deba@2480
  1560
	_kuratowski.set(path[i], true);
deba@2480
  1561
      }
deba@2480
  1562
    }
deba@2480
  1563
deba@2480
  1564
    void markPilePath(std::vector<Edge>& path) {
deba@2480
  1565
      for (int i = 0; i < int(path.size()); ++i) {
deba@2480
  1566
	_kuratowski.set(path[i], true);
deba@2480
  1567
      }
deba@2480
  1568
    }
deba@2480
  1569
deba@2480
  1570
    void isolateKuratowski(Edge edge, NodeData& node_data, 
deba@2480
  1571
			   EdgeLists& edge_lists, FlipMap& flip_map,
deba@2480
  1572
			   OrderMap& order_map, OrderList& order_list, 
deba@2480
  1573
			   PredMap& pred_map, ChildLists& child_lists,
deba@2480
  1574
			   AncestorMap& ancestor_map, LowMap& low_map, 
deba@2480
  1575
			   EmbedEdge& embed_edge, MergeRoots& merge_roots) {
deba@2480
  1576
deba@2480
  1577
      Node root = _ugraph.source(edge);
deba@2480
  1578
      Node enode = _ugraph.target(edge);
deba@2480
  1579
deba@2480
  1580
      int rorder = order_map[root];
deba@2480
  1581
deba@2480
  1582
      TypeMap type_map(_ugraph, 0);
deba@2480
  1583
deba@2480
  1584
      int rn = findComponentRoot(root, enode, child_lists, 
deba@2480
  1585
				 order_map, order_list);
deba@2480
  1586
deba@2480
  1587
      Node xnode = order_list[node_data[rn].next];
deba@2480
  1588
      Node ynode = order_list[node_data[rn].prev];
deba@2480
  1589
deba@2480
  1590
      // Minor-A
deba@2480
  1591
      {
deba@2480
  1592
	while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
deba@2480
  1593
	  
deba@2480
  1594
	  if (!merge_roots[xnode].empty()) {
deba@2480
  1595
	    root = xnode;
deba@2480
  1596
	    rn = merge_roots[xnode].front();
deba@2480
  1597
	  } else {
deba@2480
  1598
	    root = ynode;
deba@2480
  1599
	    rn = merge_roots[ynode].front();
deba@2480
  1600
	  }
deba@2480
  1601
	  
deba@2480
  1602
	  xnode = order_list[node_data[rn].next];
deba@2480
  1603
	  ynode = order_list[node_data[rn].prev];
deba@2480
  1604
	}
deba@2480
  1605
	
deba@2480
  1606
	if (root != _ugraph.source(edge)) {
deba@2480
  1607
	  orientComponent(root, rn, order_map, pred_map, 
deba@2480
  1608
			  node_data, edge_lists, flip_map, type_map);
deba@2480
  1609
	  markFacePath(root, root, order_map, node_data);
deba@2480
  1610
	  int xlp = markExternalPath(xnode, order_map, child_lists, 
deba@2480
  1611
				     pred_map, ancestor_map, low_map);
deba@2480
  1612
	  int ylp = markExternalPath(ynode, order_map, child_lists, 
deba@2480
  1613
				     pred_map, ancestor_map, low_map);
deba@2480
  1614
	  markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
deba@2480
  1615
	  Node lwnode = findPertinent(ynode, order_map, node_data,
deba@2480
  1616
				     embed_edge, merge_roots);
deba@2480
  1617
	  
deba@2480
  1618
	  markPertinentPath(lwnode, order_map, node_data, edge_lists,
deba@2480
  1619
			    embed_edge, merge_roots);
deba@2480
  1620
	  
deba@2480
  1621
	  return;
deba@2480
  1622
	}
deba@2480
  1623
      }
deba@2480
  1624
      
deba@2480
  1625
      orientComponent(root, rn, order_map, pred_map, 
deba@2480
  1626
		      node_data, edge_lists, flip_map, type_map);
deba@2480
  1627
deba@2480
  1628
      Node wnode = findPertinent(ynode, order_map, node_data,
deba@2480
  1629
				 embed_edge, merge_roots);
deba@2480
  1630
      setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
deba@2480
  1631
deba@2480
  1632
      
deba@2480
  1633
      //Minor-B
deba@2480
  1634
      if (!merge_roots[wnode].empty()) {
deba@2480
  1635
	int cn = merge_roots[wnode].back();
deba@2480
  1636
	Node rep = order_list[cn - order_list.size()];
deba@2480
  1637
	if (low_map[rep] < rorder) {
deba@2480
  1638
	  markFacePath(root, root, order_map, node_data);
deba@2480
  1639
	  int xlp = markExternalPath(xnode, order_map, child_lists, 
deba@2480
  1640
				     pred_map, ancestor_map, low_map);
deba@2480
  1641
	  int ylp = markExternalPath(ynode, order_map, child_lists, 
deba@2480
  1642
				     pred_map, ancestor_map, low_map);
deba@2480
  1643
deba@2480
  1644
	  Node lwnode, lznode;
deba@2480
  1645
	  markCommonPath(wnode, rorder, lwnode, lznode, order_list, 
deba@2480
  1646
			 order_map, node_data, edge_lists, embed_edge, 
deba@2480
  1647
			 merge_roots, child_lists, ancestor_map, low_map);
deba@2480
  1648
	  	  
deba@2480
  1649
	  markPertinentPath(lwnode, order_map, node_data, edge_lists,
deba@2480
  1650
			    embed_edge, merge_roots);
deba@2480
  1651
	  int zlp = markExternalPath(lznode, order_map, child_lists, 
deba@2480
  1652
				     pred_map, ancestor_map, low_map);
deba@2480
  1653
deba@2480
  1654
	  int minlp = xlp < ylp ? xlp : ylp;
deba@2480
  1655
	  if (zlp < minlp) minlp = zlp;
deba@2480
  1656
deba@2480
  1657
	  int maxlp = xlp > ylp ? xlp : ylp;
deba@2480
  1658
	  if (zlp > maxlp) maxlp = zlp;
deba@2480
  1659
	  
deba@2480
  1660
	  markPredPath(order_list[maxlp], order_list[minlp], pred_map);
deba@2480
  1661
	  
deba@2480
  1662
	  return;
deba@2480
  1663
	}
deba@2480
  1664
      }
deba@2480
  1665
deba@2480
  1666
      Node pxnode, pynode;
deba@2480
  1667
      std::vector<Edge> ipath;
deba@2480
  1668
      findInternalPath(ipath, wnode, root, type_map, order_map,
deba@2480
  1669
		       node_data, edge_lists);
deba@2480
  1670
      setInternalFlags(ipath, type_map);
deba@2480
  1671
      pynode = _ugraph.source(ipath.front());
deba@2480
  1672
      pxnode = _ugraph.target(ipath.back());
deba@2480
  1673
deba@2480
  1674
      wnode = findPertinent(pynode, order_map, node_data,
deba@2480
  1675
			    embed_edge, merge_roots);
deba@2480
  1676
      
deba@2480
  1677
      // Minor-C
deba@2480
  1678
      {
deba@2480
  1679
	if (type_map[_ugraph.source(ipath.front())] == HIGHY) {
deba@2480
  1680
	  if (type_map[_ugraph.target(ipath.back())] == HIGHX) {
deba@2480
  1681
	    markFacePath(xnode, pxnode, order_map, node_data);
deba@2480
  1682
	  }
deba@2480
  1683
	  markFacePath(root, xnode, order_map, node_data);
deba@2480
  1684
	  markPertinentPath(wnode, order_map, node_data, edge_lists,
deba@2480
  1685
			    embed_edge, merge_roots);
deba@2480
  1686
	  markInternalPath(ipath);
deba@2480
  1687
	  int xlp = markExternalPath(xnode, order_map, child_lists, 
deba@2480
  1688
				     pred_map, ancestor_map, low_map);
deba@2480
  1689
	  int ylp = markExternalPath(ynode, order_map, child_lists, 
deba@2480
  1690
				     pred_map, ancestor_map, low_map);
deba@2480
  1691
	  markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
deba@2480
  1692
	  return;
deba@2480
  1693
	}
deba@2480
  1694
deba@2480
  1695
	if (type_map[_ugraph.target(ipath.back())] == HIGHX) {
deba@2480
  1696
	  markFacePath(ynode, root, order_map, node_data);
deba@2480
  1697
	  markPertinentPath(wnode, order_map, node_data, edge_lists,
deba@2480
  1698
			    embed_edge, merge_roots);
deba@2480
  1699
	  markInternalPath(ipath);
deba@2480
  1700
	  int xlp = markExternalPath(xnode, order_map, child_lists, 
deba@2480
  1701
				     pred_map, ancestor_map, low_map);
deba@2480
  1702
	  int ylp = markExternalPath(ynode, order_map, child_lists, 
deba@2480
  1703
				     pred_map, ancestor_map, low_map);
deba@2480
  1704
	  markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
deba@2480
  1705
	  return;
deba@2480
  1706
	}
deba@2480
  1707
      }
deba@2480
  1708
deba@2480
  1709
      std::vector<Edge> ppath;
deba@2480
  1710
      findPilePath(ppath, root, type_map, order_map, node_data, edge_lists);
deba@2480
  1711
      
deba@2480
  1712
      // Minor-D
deba@2480
  1713
      if (!ppath.empty()) {
deba@2480
  1714
	markFacePath(ynode, xnode, order_map, node_data);
deba@2480
  1715
	markPertinentPath(wnode, order_map, node_data, edge_lists,
deba@2480
  1716
			  embed_edge, merge_roots);
deba@2480
  1717
	markPilePath(ppath);
deba@2480
  1718
	markInternalPath(ipath);
deba@2480
  1719
	int xlp = markExternalPath(xnode, order_map, child_lists, 
deba@2480
  1720
				   pred_map, ancestor_map, low_map);
deba@2480
  1721
	int ylp = markExternalPath(ynode, order_map, child_lists, 
deba@2480
  1722
				   pred_map, ancestor_map, low_map);
deba@2480
  1723
	markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
deba@2480
  1724
	return;
deba@2480
  1725
      }
deba@2480
  1726
deba@2480
  1727
      // Minor-E*
deba@2480
  1728
      {
deba@2480
  1729
deba@2480
  1730
	if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
deba@2480
  1731
	  Node znode = findExternal(pynode, rorder, order_map, 
deba@2480
  1732
				    child_lists, ancestor_map,
deba@2480
  1733
				    low_map, node_data);
deba@2480
  1734
	  
deba@2480
  1735
	  if (type_map[znode] == LOWY) {
deba@2480
  1736
	    markFacePath(root, xnode, order_map, node_data);
deba@2480
  1737
	    markPertinentPath(wnode, order_map, node_data, edge_lists,
deba@2480
  1738
			      embed_edge, merge_roots);
deba@2480
  1739
	    markInternalPath(ipath);
deba@2480
  1740
	    int xlp = markExternalPath(xnode, order_map, child_lists, 
deba@2480
  1741
				       pred_map, ancestor_map, low_map);
deba@2480
  1742
	    int zlp = markExternalPath(znode, order_map, child_lists, 
deba@2480
  1743
				       pred_map, ancestor_map, low_map);
deba@2480
  1744
	    markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
deba@2480
  1745
	  } else {
deba@2480
  1746
	    markFacePath(ynode, root, order_map, node_data);
deba@2480
  1747
	    markPertinentPath(wnode, order_map, node_data, edge_lists,
deba@2480
  1748
			      embed_edge, merge_roots);
deba@2480
  1749
	    markInternalPath(ipath);
deba@2480
  1750
	    int ylp = markExternalPath(ynode, order_map, child_lists, 
deba@2480
  1751
				       pred_map, ancestor_map, low_map);
deba@2480
  1752
	    int zlp = markExternalPath(znode, order_map, child_lists, 
deba@2480
  1753
				       pred_map, ancestor_map, low_map);
deba@2480
  1754
	    markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
deba@2480
  1755
	  }
deba@2480
  1756
	  return;
deba@2480
  1757
	}
deba@2480
  1758
deba@2480
  1759
	int xlp = markExternalPath(xnode, order_map, child_lists, 
deba@2480
  1760
				   pred_map, ancestor_map, low_map);
deba@2480
  1761
	int ylp = markExternalPath(ynode, order_map, child_lists, 
deba@2480
  1762
				   pred_map, ancestor_map, low_map);
deba@2480
  1763
	int wlp = markExternalPath(wnode, order_map, child_lists, 
deba@2480
  1764
				   pred_map, ancestor_map, low_map);
deba@2480
  1765
deba@2480
  1766
	if (wlp > xlp && wlp > ylp) {
deba@2480
  1767
	  markFacePath(root, root, order_map, node_data);
deba@2480
  1768
	  markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
deba@2480
  1769
	  return;
deba@2480
  1770
	}
deba@2480
  1771
deba@2480
  1772
	markInternalPath(ipath);
deba@2480
  1773
	markPertinentPath(wnode, order_map, node_data, edge_lists,
deba@2480
  1774
			  embed_edge, merge_roots);
deba@2480
  1775
deba@2480
  1776
	if (xlp > ylp && xlp > wlp) {
deba@2480
  1777
	  markFacePath(root, pynode, order_map, node_data);
deba@2480
  1778
	  markFacePath(wnode, xnode, order_map, node_data);
deba@2480
  1779
	  markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
deba@2480
  1780
	  return;
deba@2480
  1781
	}
deba@2480
  1782
deba@2480
  1783
	if (ylp > xlp && ylp > wlp) {
deba@2480
  1784
	  markFacePath(pxnode, root, order_map, node_data);
deba@2480
  1785
	  markFacePath(ynode, wnode, order_map, node_data);
deba@2480
  1786
	  markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
deba@2480
  1787
	  return;
deba@2480
  1788
	}
deba@2480
  1789
deba@2480
  1790
	if (pynode != ynode) {
deba@2480
  1791
	  markFacePath(pxnode, wnode, order_map, node_data);
deba@2480
  1792
deba@2480
  1793
	  int minlp = xlp < ylp ? xlp : ylp;
deba@2480
  1794
	  if (wlp < minlp) minlp = wlp;
deba@2480
  1795
deba@2480
  1796
	  int maxlp = xlp > ylp ? xlp : ylp;
deba@2480
  1797
	  if (wlp > maxlp) maxlp = wlp;
deba@2480
  1798
	  
deba@2480
  1799
	  markPredPath(order_list[maxlp], order_list[minlp], pred_map);
deba@2480
  1800
	  return;
deba@2480
  1801
	}
deba@2480
  1802
deba@2480
  1803
	if (pxnode != xnode) {
deba@2480
  1804
	  markFacePath(wnode, pynode, order_map, node_data);
deba@2480
  1805
deba@2480
  1806
	  int minlp = xlp < ylp ? xlp : ylp;
deba@2480
  1807
	  if (wlp < minlp) minlp = wlp;
deba@2480
  1808
deba@2480
  1809
	  int maxlp = xlp > ylp ? xlp : ylp;
deba@2480
  1810
	  if (wlp > maxlp) maxlp = wlp;
deba@2480
  1811
	  
deba@2480
  1812
	  markPredPath(order_list[maxlp], order_list[minlp], pred_map);
deba@2480
  1813
	  return;
deba@2480
  1814
	}
deba@2480
  1815
deba@2480
  1816
	markFacePath(root, root, order_map, node_data);
deba@2480
  1817
	int minlp = xlp < ylp ? xlp : ylp;
deba@2480
  1818
	if (wlp < minlp) minlp = wlp;
deba@2480
  1819
	markPredPath(root, order_list[minlp], pred_map);
deba@2480
  1820
	return;
deba@2480
  1821
      }
deba@2480
  1822
      
deba@2480
  1823
    }
deba@2480
  1824
deba@2480
  1825
  };
deba@2480
  1826
deba@2499
  1827
  namespace _planarity_bits {
deba@2499
  1828
deba@2499
  1829
    template <typename UGraph, typename EmbeddingMap>
deba@2499
  1830
    void makeConnected(UGraph& ugraph, EmbeddingMap& embedding) {
deba@2499
  1831
      DfsVisitor<UGraph> null_visitor;
deba@2499
  1832
      DfsVisit<UGraph, DfsVisitor<UGraph> > dfs(ugraph, null_visitor);
deba@2499
  1833
      dfs.init();
deba@2499
  1834
deba@2499
  1835
      typename UGraph::Node u = INVALID;
deba@2499
  1836
      for (typename UGraph::NodeIt n(ugraph); n != INVALID; ++n) {
deba@2499
  1837
	if (!dfs.reached(n)) {
deba@2499
  1838
	  dfs.addSource(n);
deba@2499
  1839
	  dfs.start();
deba@2499
  1840
	  if (u == INVALID) {
deba@2499
  1841
	    u = n;
deba@2499
  1842
	  } else {
deba@2499
  1843
	    typename UGraph::Node v = n;
deba@2499
  1844
	    
deba@2499
  1845
	    typename UGraph::Edge ue = typename UGraph::OutEdgeIt(ugraph, u);
deba@2499
  1846
	    typename UGraph::Edge ve = typename UGraph::OutEdgeIt(ugraph, v);
deba@2499
  1847
deba@2499
  1848
	    typename UGraph::Edge e = ugraph.direct(ugraph.addEdge(u, v), true);
deba@2499
  1849
	    
deba@2499
  1850
	    if (ue != INVALID) {
deba@2499
  1851
	      embedding[e] = embedding[ue];
deba@2499
  1852
	      embedding[ue] = e;
deba@2499
  1853
	    } else {
deba@2499
  1854
	      embedding[e] = e;
deba@2499
  1855
	    }
deba@2499
  1856
deba@2499
  1857
	    if (ve != INVALID) {
deba@2499
  1858
	      embedding[ugraph.oppositeEdge(e)] = embedding[ve];
deba@2499
  1859
	      embedding[ve] = ugraph.oppositeEdge(e);
deba@2499
  1860
	    } else {
deba@2499
  1861
	      embedding[ugraph.oppositeEdge(e)] = ugraph.oppositeEdge(e);
deba@2499
  1862
	    }
deba@2499
  1863
	  }
deba@2499
  1864
	}
deba@2499
  1865
      }
deba@2499
  1866
    }
deba@2499
  1867
deba@2499
  1868
    template <typename UGraph, typename EmbeddingMap>
deba@2499
  1869
    void makeBiNodeConnected(UGraph& ugraph, EmbeddingMap& embedding) {
deba@2499
  1870
      typename UGraph::template EdgeMap<bool> processed(ugraph);
deba@2499
  1871
deba@2499
  1872
      std::vector<typename UGraph::Edge> edges;
deba@2499
  1873
      for (typename UGraph::EdgeIt e(ugraph); e != INVALID; ++e) {
deba@2499
  1874
	edges.push_back(e);
deba@2499
  1875
      }
deba@2499
  1876
deba@2499
  1877
      IterableBoolMap<UGraph, typename UGraph::Node> visited(ugraph, false);
deba@2499
  1878
      
deba@2499
  1879
      for (int i = 0; i < int(edges.size()); ++i) {
deba@2499
  1880
	typename UGraph::Edge pp = edges[i];
deba@2499
  1881
	if (processed[pp]) continue;
deba@2499
  1882
deba@2499
  1883
	typename UGraph::Edge e = embedding[ugraph.oppositeEdge(pp)];
deba@2499
  1884
	processed[e] = true;
deba@2499
  1885
	visited.set(ugraph.source(e), true);
deba@2499
  1886
	
deba@2499
  1887
	typename UGraph::Edge p = e, l = e;
deba@2499
  1888
	e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  1889
	
deba@2499
  1890
	while (e != l) {
deba@2499
  1891
	  processed[e] = true;
deba@2499
  1892
deba@2499
  1893
	  if (visited[ugraph.source(e)]) {
deba@2499
  1894
	    
deba@2499
  1895
	    typename UGraph::Edge n = 
deba@2499
  1896
	      ugraph.direct(ugraph.addEdge(ugraph.source(p), 
deba@2499
  1897
					   ugraph.target(e)), true);
deba@2499
  1898
	    embedding[n] = p;
deba@2499
  1899
	    embedding[ugraph.oppositeEdge(pp)] = n;
deba@2499
  1900
deba@2499
  1901
	    embedding[ugraph.oppositeEdge(n)] = 
deba@2499
  1902
	      embedding[ugraph.oppositeEdge(e)];
deba@2499
  1903
	    embedding[ugraph.oppositeEdge(e)] = 
deba@2499
  1904
	      ugraph.oppositeEdge(n);
deba@2499
  1905
	    
deba@2499
  1906
	    p = n;
deba@2499
  1907
	    e = embedding[ugraph.oppositeEdge(n)];
deba@2499
  1908
	  } else {
deba@2499
  1909
	    visited.set(ugraph.source(e), true);
deba@2499
  1910
	    pp = p;
deba@2499
  1911
	    p = e;
deba@2499
  1912
	    e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  1913
	  }
deba@2499
  1914
	}
deba@2499
  1915
	visited.setAll(false);
deba@2499
  1916
      }
deba@2499
  1917
    }
deba@2499
  1918
    
deba@2499
  1919
    
deba@2499
  1920
    template <typename UGraph, typename EmbeddingMap>
deba@2499
  1921
    void makeMaxPlanar(UGraph& ugraph, EmbeddingMap& embedding) {
deba@2499
  1922
      
deba@2499
  1923
      typename UGraph::template NodeMap<int> degree(ugraph);
deba@2499
  1924
deba@2499
  1925
      for (typename UGraph::NodeIt n(ugraph); n != INVALID; ++n) {
deba@2499
  1926
	degree[n] = countIncEdges(ugraph, n);
deba@2499
  1927
      }
deba@2499
  1928
deba@2499
  1929
      typename UGraph::template EdgeMap<bool> processed(ugraph);
deba@2499
  1930
      IterableBoolMap<UGraph, typename UGraph::Node> visited(ugraph, false);
deba@2499
  1931
deba@2499
  1932
      std::vector<typename UGraph::Edge> edges;
deba@2499
  1933
      for (typename UGraph::EdgeIt e(ugraph); e != INVALID; ++e) {
deba@2499
  1934
	edges.push_back(e);
deba@2499
  1935
      }
deba@2499
  1936
deba@2499
  1937
      for (int i = 0; i < int(edges.size()); ++i) {
deba@2499
  1938
	typename UGraph::Edge e = edges[i];
deba@2499
  1939
deba@2499
  1940
	if (processed[e]) continue;
deba@2499
  1941
	processed[e] = true;
deba@2499
  1942
deba@2499
  1943
	typename UGraph::Edge mine = e;
deba@2499
  1944
	int mind = degree[ugraph.source(e)];
deba@2499
  1945
deba@2499
  1946
	int face_size = 1;	
deba@2499
  1947
deba@2499
  1948
	typename UGraph::Edge l = e;
deba@2499
  1949
	e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  1950
	while (l != e) {
deba@2499
  1951
	  processed[e] = true;
deba@2499
  1952
deba@2499
  1953
	  ++face_size;
deba@2499
  1954
deba@2499
  1955
	  if (degree[ugraph.source(e)] < mind) {
deba@2499
  1956
	    mine = e;
deba@2499
  1957
	    mind = degree[ugraph.source(e)];
deba@2499
  1958
	  }
deba@2499
  1959
	  
deba@2499
  1960
	  e = embedding[ugraph.oppositeEdge(e)];	  
deba@2499
  1961
	}
deba@2499
  1962
	
deba@2499
  1963
	if (face_size < 4) {
deba@2499
  1964
	  continue;
deba@2499
  1965
	}
deba@2499
  1966
deba@2499
  1967
	typename UGraph::Node s = ugraph.source(mine);
deba@2499
  1968
	for (typename UGraph::OutEdgeIt e(ugraph, s); e != INVALID; ++e) {
deba@2499
  1969
	  visited.set(ugraph.target(e), true); 
deba@2499
  1970
	}
deba@2499
  1971
deba@2499
  1972
	typename UGraph::Edge oppe = INVALID;
deba@2499
  1973
deba@2499
  1974
	e = embedding[ugraph.oppositeEdge(mine)];
deba@2499
  1975
	e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  1976
	while (ugraph.target(e) != s) {
deba@2499
  1977
	  if (visited[ugraph.source(e)]) {
deba@2499
  1978
	    oppe = e;
deba@2499
  1979
	    break;
deba@2499
  1980
	  }
deba@2499
  1981
	  e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  1982
	}
deba@2499
  1983
	visited.setAll(false);
deba@2499
  1984
	
deba@2499
  1985
	if (oppe == INVALID) {
deba@2499
  1986
deba@2499
  1987
	  e = embedding[ugraph.oppositeEdge(mine)];
deba@2499
  1988
	  typename UGraph::Edge pn = mine, p = e;
deba@2499
  1989
deba@2499
  1990
	  e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  1991
	  while (ugraph.target(e) != s) {
deba@2499
  1992
	    typename UGraph::Edge n = 
deba@2499
  1993
	      ugraph.direct(ugraph.addEdge(s, ugraph.source(e)), true);
deba@2499
  1994
deba@2499
  1995
	    embedding[n] = pn;
deba@2499
  1996
	    embedding[ugraph.oppositeEdge(n)] = e;
deba@2499
  1997
	    embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
deba@2499
  1998
deba@2499
  1999
	    pn = n;
deba@2499
  2000
	    
deba@2499
  2001
	    p = e;
deba@2499
  2002
	    e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  2003
	  }
deba@2499
  2004
deba@2499
  2005
	  embedding[ugraph.oppositeEdge(e)] = pn;
deba@2499
  2006
deba@2499
  2007
	} else {
deba@2499
  2008
deba@2499
  2009
	  mine = embedding[ugraph.oppositeEdge(mine)];
deba@2499
  2010
	  s = ugraph.source(mine);
deba@2499
  2011
	  oppe = embedding[ugraph.oppositeEdge(oppe)];
deba@2499
  2012
	  typename UGraph::Node t = ugraph.source(oppe);
deba@2499
  2013
	  
deba@2499
  2014
	  typename UGraph::Edge ce = ugraph.direct(ugraph.addEdge(s, t), true);
deba@2499
  2015
	  embedding[ce] = mine;
deba@2499
  2016
	  embedding[ugraph.oppositeEdge(ce)] = oppe;
deba@2499
  2017
deba@2499
  2018
	  typename UGraph::Edge pn = ce, p = oppe;	  
deba@2499
  2019
	  e = embedding[ugraph.oppositeEdge(oppe)];
deba@2499
  2020
	  while (ugraph.target(e) != s) {
deba@2499
  2021
	    typename UGraph::Edge n = 
deba@2499
  2022
	      ugraph.direct(ugraph.addEdge(s, ugraph.source(e)), true);
deba@2499
  2023
deba@2499
  2024
	    embedding[n] = pn;
deba@2499
  2025
	    embedding[ugraph.oppositeEdge(n)] = e;
deba@2499
  2026
	    embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
deba@2499
  2027
deba@2499
  2028
	    pn = n;
deba@2499
  2029
	    
deba@2499
  2030
	    p = e;
deba@2499
  2031
	    e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  2032
	    
deba@2499
  2033
	  }
deba@2499
  2034
	  embedding[ugraph.oppositeEdge(e)] = pn;
deba@2499
  2035
deba@2499
  2036
	  pn = ugraph.oppositeEdge(ce), p = mine;	  
deba@2499
  2037
	  e = embedding[ugraph.oppositeEdge(mine)];
deba@2499
  2038
	  while (ugraph.target(e) != t) {
deba@2499
  2039
	    typename UGraph::Edge n = 
deba@2499
  2040
	      ugraph.direct(ugraph.addEdge(t, ugraph.source(e)), true);
deba@2499
  2041
deba@2499
  2042
	    embedding[n] = pn;
deba@2499
  2043
	    embedding[ugraph.oppositeEdge(n)] = e;
deba@2499
  2044
	    embedding[ugraph.oppositeEdge(p)] = ugraph.oppositeEdge(n);
deba@2499
  2045
deba@2499
  2046
	    pn = n;
deba@2499
  2047
	    
deba@2499
  2048
	    p = e;
deba@2499
  2049
	    e = embedding[ugraph.oppositeEdge(e)];
deba@2499
  2050
	    
deba@2499
  2051
	  }
deba@2499
  2052
	  embedding[ugraph.oppositeEdge(e)] = pn;
deba@2499
  2053
	}
deba@2499
  2054
      }
deba@2499
  2055
    }
deba@2499
  2056
deba@2499
  2057
  }
deba@2499
  2058
deba@2500
  2059
  /// \ingroup planar
deba@2500
  2060
  ///
deba@2499
  2061
  /// \brief Schnyder's planar drawing algorithms
deba@2499
  2062
  ///
deba@2499
  2063
  /// The planar drawing algorithm calculates location for each node
deba@2499
  2064
  /// in the plane, which coordinates satisfies that if each edge is
deba@2499
  2065
  /// represented with a straight line then the edges will not
deba@2499
  2066
  /// intersect each other.
deba@2499
  2067
  ///
deba@2499
  2068
  /// Scnyder's algorithm embeds the graph on \c (n-2,n-2) size grid,
deba@2499
  2069
  /// ie. each node will be located in the \c [0,n-2]x[0,n-2] square.
deba@2499
  2070
  /// The time complexity of the algorithm is O(n).
deba@2499
  2071
  template <typename UGraph>
deba@2499
  2072
  class PlanarDrawing {
deba@2499
  2073
  public:
deba@2499
  2074
deba@2499
  2075
    UGRAPH_TYPEDEFS(typename UGraph);
deba@2499
  2076
deba@2499
  2077
    /// \brief The point type for store coordinates
deba@2499
  2078
    typedef dim2::Point<int> Point;
deba@2499
  2079
    /// \brief The map type for store coordinates
deba@2499
  2080
    typedef typename UGraph::template NodeMap<Point> PointMap;
deba@2499
  2081
deba@2499
  2082
deba@2499
  2083
    /// \brief Constructor
deba@2499
  2084
    ///
deba@2499
  2085
    /// Constructor
deba@2499
  2086
    /// \pre The ugraph should be simple, ie. loop and parallel edge free. 
deba@2499
  2087
    PlanarDrawing(const UGraph& ugraph)
deba@2499
  2088
      : _ugraph(ugraph), _point_map(ugraph) {}
deba@2499
  2089
deba@2499
  2090
  private:
deba@2499
  2091
deba@2499
  2092
    template <typename AuxUGraph, typename AuxEmbeddingMap>
deba@2499
  2093
    void drawing(const AuxUGraph& ugraph, 
deba@2499
  2094
		 const AuxEmbeddingMap& next, 
deba@2499
  2095
		 PointMap& point_map) {
deba@2499
  2096
      UGRAPH_TYPEDEFS(typename AuxUGraph);
deba@2499
  2097
deba@2499
  2098
      typename AuxUGraph::template EdgeMap<Edge> prev(ugraph);
deba@2499
  2099
deba@2499
  2100
      for (NodeIt n(ugraph); n != INVALID; ++n) {
deba@2499
  2101
	Edge e = OutEdgeIt(ugraph, n);
deba@2499
  2102
	
deba@2499
  2103
	Edge p = e, l = e;
deba@2499
  2104
	
deba@2499
  2105
	e = next[e];
deba@2499
  2106
	while (e != l) {
deba@2499
  2107
	  prev[e] = p;
deba@2499
  2108
	  p = e;
deba@2499
  2109
	  e = next[e];
deba@2499
  2110
	}
deba@2499
  2111
	prev[e] = p;
deba@2499
  2112
      }
deba@2499
  2113
deba@2499
  2114
      Node anode, bnode, cnode;
deba@2499
  2115
deba@2499
  2116
      {
deba@2499
  2117
	Edge e = EdgeIt(ugraph);
deba@2499
  2118
	anode = ugraph.source(e);
deba@2499
  2119
	bnode = ugraph.target(e);
deba@2499
  2120
	cnode = ugraph.target(next[ugraph.oppositeEdge(e)]);
deba@2499
  2121
      }
deba@2499
  2122
      
deba@2499
  2123
      IterableBoolMap<AuxUGraph, Node> proper(ugraph, false);
deba@2499
  2124
      typename AuxUGraph::template NodeMap<int> conn(ugraph, -1);
deba@2499
  2125
deba@2499
  2126
      conn[anode] = conn[bnode] = -2;      
deba@2499
  2127
      {
deba@2499
  2128
	for (OutEdgeIt e(ugraph, anode); e != INVALID; ++e) {
deba@2499
  2129
	  Node m = ugraph.target(e);
deba@2499
  2130
	  if (conn[m] == -1) {
deba@2499
  2131
	    conn[m] = 1;
deba@2499
  2132
	  }
deba@2499
  2133
	}
deba@2499
  2134
	conn[cnode] = 2;
deba@2499
  2135
deba@2499
  2136
	for (OutEdgeIt e(ugraph, bnode); e != INVALID; ++e) {
deba@2499
  2137
	  Node m = ugraph.target(e);
deba@2499
  2138
	  if (conn[m] == -1) {
deba@2499
  2139
	    conn[m] = 1;
deba@2499
  2140
	  } else if (conn[m] != -2) {
deba@2499
  2141
	    conn[m] += 1;	    
deba@2499
  2142
	    Edge pe = ugraph.oppositeEdge(e);
deba@2499
  2143
	    if (conn[ugraph.target(next[pe])] == -2) {
deba@2499
  2144
	      conn[m] -= 1;
deba@2499
  2145
	    }
deba@2499
  2146
	    if (conn[ugraph.target(prev[pe])] == -2) {
deba@2499
  2147
	      conn[m] -= 1;
deba@2499
  2148
	    }
deba@2499
  2149
deba@2499
  2150
	    proper.set(m, conn[m] == 1);
deba@2499
  2151
	  }
deba@2499
  2152
	}
deba@2499
  2153
      }
deba@2499
  2154
      
deba@2499
  2155
deba@2499
  2156
      typename AuxUGraph::template EdgeMap<int> angle(ugraph, -1);
deba@2499
  2157
deba@2499
  2158
      while (proper.trueNum() != 0) {
deba@2499
  2159
	Node n = typename IterableBoolMap<AuxUGraph, Node>::TrueIt(proper);
deba@2499
  2160
	proper.set(n, false);
deba@2499
  2161
	conn[n] = -2;
deba@2499
  2162
deba@2499
  2163
	for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
deba@2499
  2164
	  Node m = ugraph.target(e);
deba@2499
  2165
	  if (conn[m] == -1) {
deba@2499
  2166
	    conn[m] = 1;
deba@2499
  2167
	  } else if (conn[m] != -2) {
deba@2499
  2168
	    conn[m] += 1;	    
deba@2499
  2169
	    Edge pe = ugraph.oppositeEdge(e);
deba@2499
  2170
	    if (conn[ugraph.target(next[pe])] == -2) {
deba@2499
  2171
	      conn[m] -= 1;
deba@2499
  2172
	    }
deba@2499
  2173
	    if (conn[ugraph.target(prev[pe])] == -2) {
deba@2499
  2174
	      conn[m] -= 1;
deba@2499
  2175
	    }
deba@2499
  2176
deba@2499
  2177
	    proper.set(m, conn[m] == 1);
deba@2499
  2178
	  }
deba@2499
  2179
	}
deba@2499
  2180
deba@2499
  2181
	{
deba@2499
  2182
	  Edge e = OutEdgeIt(ugraph, n);
deba@2499
  2183
	  Edge p = e, l = e;
deba@2499
  2184
	  
deba@2499
  2185
	  e = next[e];
deba@2499
  2186
	  while (e != l) {
deba@2499
  2187
	    
deba@2499
  2188
	    if (conn[ugraph.target(e)] == -2 && conn[ugraph.target(p)] == -2) {
deba@2499
  2189
	      Edge f = e;
deba@2499
  2190
	      angle[f] = 0;
deba@2499
  2191
	      f = next[ugraph.oppositeEdge(f)];
deba@2499
  2192
	      angle[f] = 1;
deba@2499
  2193
	      f = next[ugraph.oppositeEdge(f)];
deba@2499
  2194
	      angle[f] = 2;
deba@2499
  2195
	    }
deba@2499
  2196
	    
deba@2499
  2197
	    p = e;
deba@2499
  2198
	    e = next[e];
deba@2499
  2199
	  }
deba@2499
  2200
	  
deba@2499
  2201
	  if (conn[ugraph.target(e)] == -2 && conn[ugraph.target(p)] == -2) {
deba@2499
  2202
	    Edge f = e;
deba@2499
  2203
	    angle[f] = 0;
deba@2499
  2204
	    f = next[ugraph.oppositeEdge(f)];
deba@2499
  2205
	    angle[f] = 1;
deba@2499
  2206
	    f = next[ugraph.oppositeEdge(f)];
deba@2499
  2207
	    angle[f] = 2;
deba@2499
  2208
	  }
deba@2499
  2209
	}
deba@2499
  2210
      }
deba@2499
  2211
deba@2499
  2212
      typename AuxUGraph::template NodeMap<Node> apred(ugraph, INVALID);
deba@2499
  2213
      typename AuxUGraph::template NodeMap<Node> bpred(ugraph, INVALID);
deba@2499
  2214
      typename AuxUGraph::template NodeMap<Node> cpred(ugraph, INVALID);
deba@2499
  2215
deba@2499
  2216
      typename AuxUGraph::template NodeMap<int> apredid(ugraph, -1);
deba@2499
  2217
      typename AuxUGraph::template NodeMap<int> bpredid(ugraph, -1);
deba@2499
  2218
      typename AuxUGraph::template NodeMap<int> cpredid(ugraph, -1);
deba@2499
  2219
deba@2499
  2220
      for (EdgeIt e(ugraph); e != INVALID; ++e) {
deba@2499
  2221
	if (angle[e] == angle[next[e]]) {
deba@2499
  2222
	  switch (angle[e]) {
deba@2499
  2223
	  case 2:
deba@2499
  2224
	    apred[ugraph.target(e)] = ugraph.source(e);
deba@2499
  2225
	    apredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
deba@2499
  2226
	    break;
deba@2499
  2227
	  case 1:
deba@2499
  2228
	    bpred[ugraph.target(e)] = ugraph.source(e);
deba@2499
  2229
	    bpredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
deba@2499
  2230
	    break;
deba@2499
  2231
	  case 0:
deba@2499
  2232
	    cpred[ugraph.target(e)] = ugraph.source(e);
deba@2499
  2233
	    cpredid[ugraph.target(e)] = ugraph.id(ugraph.source(e));
deba@2499
  2234
	    break;
deba@2499
  2235
	  }
deba@2499
  2236
	}
deba@2499
  2237
      }
deba@2499
  2238
deba@2499
  2239
      cpred[anode] = INVALID;
deba@2499
  2240
      cpred[bnode] = INVALID;
deba@2499
  2241
deba@2499
  2242
      std::vector<Node> aorder, border, corder; 
deba@2499
  2243
deba@2499
  2244
      {
deba@2499
  2245
	typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
deba@2499
  2246
	std::vector<Node> st;
deba@2499
  2247
	for (NodeIt n(ugraph); n != INVALID; ++n) {
deba@2499
  2248
	  if (!processed[n] && n != bnode && n != cnode) {
deba@2499
  2249
	    st.push_back(n);
deba@2499
  2250
	    processed[n] = true;
deba@2499
  2251
	    Node m = apred[n];
deba@2499
  2252
	    while (m != INVALID && !processed[m]) {
deba@2499
  2253
	      st.push_back(m);
deba@2499
  2254
	      processed[m] = true;
deba@2499
  2255
	      m = apred[m];
deba@2499
  2256
	    }
deba@2499
  2257
	    while (!st.empty()) {
deba@2499
  2258
	      aorder.push_back(st.back());
deba@2499
  2259
	      st.pop_back();
deba@2499
  2260
	    }
deba@2499
  2261
	  }
deba@2499
  2262
	}
deba@2499
  2263
      }
deba@2499
  2264
deba@2499
  2265
      {
deba@2499
  2266
	typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
deba@2499
  2267
	std::vector<Node> st;
deba@2499
  2268
	for (NodeIt n(ugraph); n != INVALID; ++n) {
deba@2499
  2269
	  if (!processed[n] && n != cnode && n != anode) {
deba@2499
  2270
	    st.push_back(n);
deba@2499
  2271
	    processed[n] = true;
deba@2499
  2272
	    Node m = bpred[n];
deba@2499
  2273
	    while (m != INVALID && !processed[m]) {
deba@2499
  2274
	      st.push_back(m);
deba@2499
  2275
	      processed[m] = true;
deba@2499
  2276
	      m = bpred[m];
deba@2499
  2277
	    }
deba@2499
  2278
	    while (!st.empty()) {
deba@2499
  2279
	      border.push_back(st.back());
deba@2499
  2280
	      st.pop_back();
deba@2499
  2281
	    }
deba@2499
  2282
	  }
deba@2499
  2283
	}
deba@2499
  2284
      }
deba@2499
  2285
deba@2499
  2286
      {
deba@2499
  2287
	typename AuxUGraph::template NodeMap<bool> processed(ugraph, false);
deba@2499
  2288
	std::vector<Node> st;
deba@2499
  2289
	for (NodeIt n(ugraph); n != INVALID; ++n) {
deba@2499
  2290
	  if (!processed[n] && n != anode && n != bnode) {
deba@2499
  2291
	    st.push_back(n);
deba@2499
  2292
	    processed[n] = true;
deba@2499
  2293
	    Node m = cpred[n];
deba@2499
  2294
	    while (m != INVALID && !processed[m]) {
deba@2499
  2295
	      st.push_back(m);
deba@2499
  2296
	      processed[m] = true;
deba@2499
  2297
	      m = cpred[m];
deba@2499
  2298
	    }
deba@2499
  2299
	    while (!st.empty()) {
deba@2499
  2300
	      corder.push_back(st.back());
deba@2499
  2301
	      st.pop_back();
deba@2499
  2302
	    }
deba@2499
  2303
	  }
deba@2499
  2304
	}
deba@2499
  2305
      }
deba@2499
  2306
deba@2499
  2307
      typename AuxUGraph::template NodeMap<int> atree(ugraph, 0);
deba@2499
  2308
      for (int i = aorder.size() - 1; i >= 0; --i) {
deba@2499
  2309
	Node n = aorder[i];
deba@2499
  2310
	atree[n] = 1;
deba@2499
  2311
	for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
deba@2499
  2312
	  if (apred[ugraph.target(e)] == n) {
deba@2499
  2313
	    atree[n] += atree[ugraph.target(e)];
deba@2499
  2314
	  }
deba@2499
  2315
	} 
deba@2499
  2316
      }
deba@2499
  2317
deba@2499
  2318
      typename AuxUGraph::template NodeMap<int> btree(ugraph, 0);
deba@2499
  2319
      for (int i = border.size() - 1; i >= 0; --i) {
deba@2499
  2320
	Node n = border[i];
deba@2499
  2321
	btree[n] = 1;
deba@2499
  2322
	for (OutEdgeIt e(ugraph, n); e != INVALID; ++e) {
deba@2499
  2323
	  if (bpred[ugraph.target(e)] == n) {
deba@2499
  2324
	    btree[n] += btree[ugraph.target(e)];
deba@2499
  2325
	  }
deba@2499
  2326
	} 
deba@2499
  2327
      }
deba@2499
  2328
      
deba@2499
  2329
      typename AuxUGraph::template NodeMap<int> apath(ugraph, 0);
deba@2499
  2330
      apath[bnode] = apath[cnode] = 1;
deba@2499
  2331
      typename AuxUGraph::template NodeMap<int> apath_btree(ugraph, 0);
deba@2499
  2332
      apath_btree[bnode] = btree[bnode];
deba@2499
  2333
      for (int i = 1; i < int(aorder.size()); ++i) {
deba@2499
  2334
	Node n = aorder[i];
deba@2499
  2335
	apath[n] = apath[apred[n]] + 1;
deba@2499
  2336
	apath_btree[n] = btree[n] + apath_btree[apred[n]];
deba@2499
  2337
      }
deba@2499
  2338
deba@2499
  2339
      typename AuxUGraph::template NodeMap<int> bpath_atree(ugraph, 0);
deba@2499
  2340
      bpath_atree[anode] = atree[anode];
deba@2499
  2341
      for (int i = 1; i < int(border.size()); ++i) {
deba@2499
  2342
	Node n = border[i];
deba@2499
  2343
	bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
deba@2499
  2344
      }
deba@2499
  2345
deba@2499
  2346
      typename AuxUGraph::template NodeMap<int> cpath(ugraph, 0);
deba@2499
  2347
      cpath[anode] = cpath[bnode] = 1;
deba@2499
  2348
      typename AuxUGraph::template NodeMap<int> cpath_atree(ugraph, 0);
deba@2499
  2349
      cpath_atree[anode] = atree[anode];
deba@2499
  2350
      typename AuxUGraph::template NodeMap<int> cpath_btree(ugraph, 0);
deba@2499
  2351
      cpath_btree[bnode] = btree[bnode];
deba@2499
  2352
      for (int i = 1; i < int(corder.size()); ++i) {
deba@2499
  2353
	Node n = corder[i];
deba@2499
  2354
	cpath[n] = cpath[cpred[n]] + 1;
deba@2499
  2355
	cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
deba@2499
  2356
	cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
deba@2499
  2357
      }
deba@2499
  2358
deba@2499
  2359
      typename AuxUGraph::template NodeMap<int> third(ugraph);
deba@2499
  2360
      for (NodeIt n(ugraph); n != INVALID; ++n) {
deba@2499
  2361
	point_map[n].x = 
deba@2499
  2362
	  bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
deba@2499
  2363
	point_map[n].y = 
deba@2499
  2364
	  cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
deba@2499
  2365
      }
deba@2499
  2366
      
deba@2499
  2367
    }
deba@2499
  2368
deba@2499
  2369
  public:
deba@2499
  2370
deba@2499
  2371
    /// \brief Calculates the node locations
deba@2499
  2372
    ///
deba@2499
  2373
    /// This function calculates the node locations.
deba@2499
  2374
    bool run() {
deba@2499
  2375
      PlanarEmbedding<UGraph> pe(_ugraph);
deba@2499
  2376
      if (!pe.run()) return false;
deba@2499
  2377
      
deba@2499
  2378
      run(pe);
deba@2499
  2379
      return true;
deba@2499
  2380
    }
deba@2499
  2381
deba@2499
  2382
    /// \brief Calculates the node locations according to a
deba@2499
  2383
    /// combinatorical embedding
deba@2499
  2384
    ///
deba@2499
  2385
    /// This function calculates the node locations. The \c embedding
deba@2499
  2386
    /// parameter should contain a valid combinatorical embedding, ie.
deba@2499
  2387
    /// a valid cyclic order of the edges.
deba@2499
  2388
    template <typename EmbeddingMap>
deba@2499
  2389
    void run(const EmbeddingMap& embedding) {
deba@2499
  2390
      typedef SmartUEdgeSet<UGraph> AuxUGraph; 
deba@2499
  2391
deba@2499
  2392
      if (3 * countNodes(_ugraph) - 6 == countUEdges(_ugraph)) {
deba@2499
  2393
	drawing(_ugraph, embedding, _point_map);
deba@2499
  2394
	return;
deba@2499
  2395
      }
deba@2499
  2396
deba@2499
  2397
      AuxUGraph aux_ugraph(_ugraph);
deba@2499
  2398
      typename AuxUGraph::template EdgeMap<typename AuxUGraph::Edge> 
deba@2499
  2399
	aux_embedding(aux_ugraph);
deba@2499
  2400
deba@2499
  2401
      {
deba@2499
  2402
deba@2499
  2403
	typename UGraph::template UEdgeMap<typename AuxUGraph::UEdge> 
deba@2499
  2404
	  ref(_ugraph);
deba@2499
  2405
	
deba@2499
  2406
	for (UEdgeIt e(_ugraph); e != INVALID; ++e) {
deba@2499
  2407
	  ref[e] = aux_ugraph.addEdge(_ugraph.source(e), _ugraph.target(e));
deba@2499
  2408
	}
deba@2499
  2409
deba@2499
  2410
	for (UEdgeIt e(_ugraph); e != INVALID; ++e) {
deba@2499
  2411
	  Edge ee = embedding[_ugraph.direct(e, true)];
deba@2499
  2412
	  aux_embedding[aux_ugraph.direct(ref[e], true)] = 
deba@2499
  2413
	    aux_ugraph.direct(ref[ee], _ugraph.direction(ee));
deba@2499
  2414
	  ee = embedding[_ugraph.direct(e, false)];
deba@2499
  2415
	  aux_embedding[aux_ugraph.direct(ref[e], false)] = 
deba@2499
  2416
	    aux_ugraph.direct(ref[ee], _ugraph.direction(ee));
deba@2499
  2417
	}
deba@2499
  2418
      }
deba@2499
  2419
      _planarity_bits::makeConnected(aux_ugraph, aux_embedding);
deba@2499
  2420
      _planarity_bits::makeBiNodeConnected(aux_ugraph, aux_embedding);
deba@2499
  2421
      _planarity_bits::makeMaxPlanar(aux_ugraph, aux_embedding);
deba@2499
  2422
      drawing(aux_ugraph, aux_embedding, _point_map);
deba@2499
  2423
    }
deba@2499
  2424
deba@2499
  2425
    /// \brief The coordinate of the given node
deba@2499
  2426
    ///
deba@2499
  2427
    /// The coordinate of the given node.
deba@2499
  2428
    Point operator[](const Node& node) {
deba@2499
  2429
      return _point_map[node];
deba@2499
  2430
    }
deba@2499
  2431
deba@2499
  2432
    /// \brief Returns the grid embedding in a \e NodeMap.
deba@2499
  2433
    ///
deba@2499
  2434
    /// Returns the grid embedding in a \e NodeMap of \c dim2::Point<int> .
deba@2499
  2435
    const PointMap& coords() const {
deba@2499
  2436
      return _point_map;
deba@2499
  2437
    }
deba@2499
  2438
deba@2499
  2439
  private:
deba@2499
  2440
    
deba@2499
  2441
    const UGraph& _ugraph;
deba@2499
  2442
    PointMap _point_map;
deba@2499
  2443
    
deba@2499
  2444
  };
deba@2499
  2445
deba@2508
  2446
  namespace _planarity_bits {
deba@2508
  2447
deba@2508
  2448
    template <typename ColorMap>
deba@2508
  2449
    class KempeFilter {
deba@2508
  2450
    public:
deba@2508
  2451
      typedef typename ColorMap::Key Key;
deba@2508
  2452
      typedef bool Value;
deba@2508
  2453
deba@2508
  2454
      KempeFilter(const ColorMap& color_map, 
deba@2508
  2455
		  const typename ColorMap::Value& first,
deba@2508
  2456
		  const typename ColorMap::Value& second)
deba@2508
  2457
	: _color_map(color_map), _first(first), _second(second) {}
deba@2508
  2458
deba@2508
  2459
      Value operator[](const Key& key) const {
deba@2508
  2460
	return _color_map[key] == _first || _color_map[key] == _second;
deba@2508
  2461
      }
deba@2508
  2462
deba@2508
  2463
    private:
deba@2508
  2464
      const ColorMap& _color_map;
deba@2508
  2465
      typename ColorMap::Value _first, _second;
deba@2508
  2466
    };
deba@2508
  2467
  }
deba@2508
  2468
deba@2508
  2469
  /// \ingroup planar
deba@2508
  2470
  ///
deba@2508
  2471
  /// \brief Coloring planar graphs
deba@2508
  2472
  ///
deba@2508
  2473
  /// The graph coloring problem is the coloring of the graph nodes
deba@2508
  2474
  /// such way that there are not adjacent nodes with the same
deba@2508
  2475
  /// color. The planar graphs can be always colored with four colors,
deba@2508
  2476
  /// it is proved by Appel and Haken and their proofs provide a
deba@2508
  2477
  /// quadratic time algorithm for four coloring, but it could not be
deba@2508
  2478
  /// used to implement efficient algorithm. The five and six coloring
deba@2508
  2479
  /// can be made in linear time, but in this class the five coloring
deba@2508
  2480
  /// has quadratic worst case time complexity. The two coloring (if
deba@2508
  2481
  /// possible) is solvable with a graph search algorithm and it is
deba@2508
  2482
  /// implemented in \ref bipartitePartitions() function in Lemon. To
deba@2508
  2483
  /// decide whether the planar graph is three colorable is
deba@2508
  2484
  /// NP-complete.
deba@2508
  2485
  ///
deba@2508
  2486
  /// This class contains member functions for calculate colorings
deba@2508
  2487
  /// with five and six colors. The six coloring algorithm is a simple
deba@2508
  2488
  /// greedy coloring on the backward minimum outgoing order of nodes.
deba@2508
  2489
  /// This order can be computed such way, that in each phase the node
deba@2508
  2490
  /// with least outgoing edges to unprocessed nodes is choosen. This
deba@2508
  2491
  /// order guarantees that at the time of coloring of a node it has
deba@2508
  2492
  /// at most five already colored adjacents. The five coloring
deba@2508
  2493
  /// algorithm works in the same way, but if the greedy approach
deba@2508
  2494
  /// fails to color with five color, ie. the node has five already
deba@2508
  2495
  /// different colored neighbours, it swaps the colors in one
deba@2508
  2496
  /// connected two colored set with the Kempe recoloring method.
deba@2508
  2497
  template <typename UGraph>
deba@2508
  2498
  class PlanarColoring {
deba@2508
  2499
  public:
deba@2508
  2500
deba@2508
  2501
    UGRAPH_TYPEDEFS(typename UGraph);
deba@2508
  2502
deba@2508
  2503
    /// \brief The map type for store color indexes
deba@2508
  2504
    typedef typename UGraph::template NodeMap<int> IndexMap;
deba@2508
  2505
    /// \brief The map type for store colors
deba@2508
  2506
    typedef ComposeMap<Palette, IndexMap> ColorMap;
deba@2508
  2507
deba@2508
  2508
    /// \brief Constructor
deba@2508
  2509
    ///
deba@2508
  2510
    /// Constructor
deba@2508
  2511
    /// \pre The ugraph should be simple, ie. loop and parallel edge free. 
deba@2508
  2512
    PlanarColoring(const UGraph& ugraph)
deba@2508
  2513
      : _ugraph(ugraph), _color_map(ugraph), _palette(0) {
deba@2508
  2514
      _palette.add(Color(1,0,0));
deba@2508
  2515
      _palette.add(Color(0,1,0));
deba@2508
  2516
      _palette.add(Color(0,0,1));
deba@2508
  2517
      _palette.add(Color(1,1,0));
deba@2508
  2518
      _palette.add(Color(1,0,1));
deba@2508
  2519
      _palette.add(Color(0,1,1));
deba@2508
  2520
    }
deba@2508
  2521
deba@2508
  2522
    /// \brief Returns the \e NodeMap of color indexes
deba@2508
  2523
    ///
deba@2508
  2524
    /// Returns the \e NodeMap of color indexes. The values are in the
deba@2508
  2525
    /// range \c [0..4] or \c [0..5] according to the five coloring or 
deba@2508
  2526
    /// six coloring.
deba@2508
  2527
    IndexMap colorIndexMap() const {
deba@2508
  2528
      return _color_map;
deba@2508
  2529
    }
deba@2508
  2530
deba@2508
  2531
    /// \brief Returns the \e NodeMap of colors
deba@2508
  2532
    ///
deba@2508
  2533
    /// Returns the \e NodeMap of colors. The values are five or six
deba@2508
  2534
    /// distinct \ref lemon::Color "colors".
deba@2508
  2535
    ColorMap colorMap() const {
deba@2508
  2536
      return composeMap(_palette, _color_map);
deba@2508
  2537
    }
deba@2508
  2538
deba@2508
  2539
    /// \brief Returns the color index of the node
deba@2508
  2540
    ///
deba@2508
  2541
    /// Returns the color index of the node. The values are in the
deba@2508
  2542
    /// range \c [0..4] or \c [0..5] according to the five coloring or
deba@2508
  2543
    /// six coloring.
deba@2508
  2544
    int colorIndex(const Node& node) const {
deba@2508
  2545
      return _color_map[node];
deba@2508
  2546
    }
deba@2508
  2547
deba@2508
  2548
    /// \brief Returns the color of the node
deba@2508
  2549
    ///
deba@2508
  2550
    /// Returns the color of the node. The values are five or six
deba@2508
  2551
    /// distinct \ref lemon::Color "colors".
deba@2598
  2552
    Color color(const Node& node) const {
deba@2508
  2553
      return _palette[_color_map[node]];
deba@2508
  2554
    }
deba@2508
  2555
    
deba@2508
  2556
deba@2508
  2557
    /// \brief Calculates a coloring with at most six colors
deba@2508
  2558
    ///
deba@2508
  2559
    /// This function calculates a coloring with at most six colors. The time
deba@2508
  2560
    /// complexity of this variant is linear in the size of the graph.
deba@2508
  2561
    /// \return %True when the algorithm could color the graph with six color.
deba@2508
  2562
    /// If the algorithm fails, then the graph could not be planar.
deba@2508
  2563
    bool runSixColoring() {
deba@2508
  2564
      
deba@2508
  2565
      typename UGraph::template NodeMap<int> heap_index(_ugraph, -1);
deba@2508
  2566
      BucketHeap<typename UGraph::template NodeMap<int> > heap(heap_index);
deba@2508
  2567
      
deba@2508
  2568
      for (NodeIt n(_ugraph); n != INVALID; ++n) {
deba@2508
  2569
	_color_map[n] = -2;
deba@2508
  2570
	heap.push(n, countOutEdges(_ugraph, n));
deba@2508
  2571
      }
deba@2508
  2572
      
deba@2508
  2573
      std::vector<Node> order;
deba@2508
  2574
      
deba@2508
  2575
      while (!heap.empty()) {
deba@2508
  2576
	Node n = heap.top();
deba@2508
  2577
	heap.pop();
deba@2508
  2578
	_color_map[n] = -1;
deba@2508
  2579
	order.push_back(n);
deba@2508
  2580
	for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
deba@2508
  2581
	  Node t = _ugraph.runningNode(e); 
deba@2508
  2582
	  if (_color_map[t] == -2) {
deba@2508
  2583
	    heap.decrease(t, heap[t] - 1);
deba@2508
  2584
	  }
deba@2508
  2585
	}
deba@2508
  2586
      }
deba@2508
  2587
deba@2508
  2588
      for (int i = order.size() - 1; i >= 0; --i) {
deba@2508
  2589
	std::vector<bool> forbidden(6, false);
deba@2508
  2590
	for (OutEdgeIt e(_ugraph, order[i]); e != INVALID; ++e) {
deba@2508
  2591
	  Node t = _ugraph.runningNode(e); 
deba@2508
  2592
	  if (_color_map[t] != -1) {
deba@2508
  2593
	    forbidden[_color_map[t]] = true;
deba@2508
  2594
	  }
deba@2508
  2595
	}
deba@2508
  2596
       	for (int k = 0; k < 6; ++k) {
deba@2508
  2597
	  if (!forbidden[k]) {
deba@2508
  2598
	    _color_map[order[i]] = k;
deba@2508
  2599
	    break;
deba@2508
  2600
	  }
deba@2508
  2601
	}
deba@2508
  2602
	if (_color_map[order[i]] == -1) {
deba@2508
  2603
	  return false;
deba@2508
  2604
	}
deba@2508
  2605
      }
deba@2508
  2606
      return true;
deba@2508
  2607
    }
deba@2508
  2608
deba@2508
  2609
  private:
deba@2508
  2610
deba@2508
  2611
    bool recolor(const Node& u, const Node& v) {
deba@2508
  2612
      int ucolor = _color_map[u];
deba@2508
  2613
      int vcolor = _color_map[v];
deba@2508
  2614
      typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
deba@2508
  2615
      KempeFilter filter(_color_map, ucolor, vcolor);
deba@2508
  2616
deba@2508
  2617
      typedef NodeSubUGraphAdaptor<const UGraph, const KempeFilter> KempeUGraph;
deba@2508
  2618
      KempeUGraph kempe_ugraph(_ugraph, filter);
deba@2508
  2619
      
deba@2508
  2620
      std::vector<Node> comp;
deba@2508
  2621
      Bfs<KempeUGraph> bfs(kempe_ugraph);
deba@2508
  2622
      bfs.init();
deba@2508
  2623
      bfs.addSource(u);
deba@2508
  2624
      while (!bfs.emptyQueue()) {
deba@2508
  2625
	Node n = bfs.nextNode();
deba@2508
  2626
	if (n == v) return false;
deba@2508
  2627
	comp.push_back(n);
deba@2508
  2628
	bfs.processNextNode();
deba@2508
  2629
      }
deba@2508
  2630
deba@2508
  2631
      int scolor = ucolor + vcolor;
deba@2508
  2632
      for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
deba@2508
  2633
	_color_map[comp[i]] = scolor - _color_map[comp[i]]; 
deba@2508
  2634
      }
deba@2508
  2635
deba@2508
  2636
      return true;
deba@2508
  2637
    }
deba@2508
  2638
deba@2508
  2639
    template <typename EmbeddingMap>
deba@2508
  2640
    void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
deba@2508
  2641
      std::vector<Node> nodes;
deba@2508
  2642
      nodes.reserve(4);
deba@2508
  2643
deba@2508
  2644
      for (Edge e = OutEdgeIt(_ugraph, node); e != INVALID; e = embedding[e]) {
deba@2508
  2645
	Node t = _ugraph.target(e); 
deba@2508
  2646
	if (_color_map[t] != -1) {
deba@2508
  2647
	  nodes.push_back(t);
deba@2508
  2648
	  if (nodes.size() == 4) break;
deba@2508
  2649
	}
deba@2508
  2650
      }
deba@2508
  2651
      
deba@2508
  2652
      int color = _color_map[nodes[0]];
deba@2508
  2653
      if (recolor(nodes[0], nodes[2])) {
deba@2508
  2654
	_color_map[node] = color;
deba@2508
  2655
      } else {
deba@2508
  2656
	color = _color_map[nodes[1]];
deba@2508
  2657
	recolor(nodes[1], nodes[3]);
deba@2508
  2658
	_color_map[node] = color;
deba@2508
  2659
      }
deba@2508
  2660
    }
deba@2508
  2661
deba@2508
  2662
  public:
deba@2508
  2663
deba@2508
  2664
    /// \brief Calculates a coloring with at most five colors
deba@2508
  2665
    ///
deba@2508
  2666
    /// This function calculates a coloring with at most five
deba@2598
  2667
    /// colors. The worst case time complexity of this variant is
deba@2508
  2668
    /// quadratic in the size of the graph.
deba@2508
  2669
    template <typename EmbeddingMap>
deba@2508
  2670
    void runFiveColoring(const EmbeddingMap& embedding) {
deba@2508
  2671
      
deba@2508
  2672
      typename UGraph::template NodeMap<int> heap_index(_ugraph, -1);
deba@2508
  2673
      BucketHeap<typename UGraph::template NodeMap<int> > heap(heap_index);
deba@2508
  2674
      
deba@2508
  2675
      for (NodeIt n(_ugraph); n != INVALID; ++n) {
deba@2508
  2676
	_color_map[n] = -2;
deba@2508
  2677
	heap.push(n, countOutEdges(_ugraph, n));
deba@2508
  2678
      }
deba@2508
  2679
      
deba@2508
  2680
      std::vector<Node> order;
deba@2508
  2681
      
deba@2508
  2682
      while (!heap.empty()) {
deba@2508
  2683
	Node n = heap.top();
deba@2508
  2684
	heap.pop();
deba@2508
  2685
	_color_map[n] = -1;
deba@2508
  2686
	order.push_back(n);
deba@2508
  2687
	for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
deba@2508
  2688
	  Node t = _ugraph.runningNode(e); 
deba@2508
  2689
	  if (_color_map[t] == -2) {
deba@2508
  2690
	    heap.decrease(t, heap[t] - 1);
deba@2508
  2691
	  }
deba@2508
  2692
	}
deba@2508
  2693
      }
deba@2508
  2694
deba@2508
  2695
      for (int i = order.size() - 1; i >= 0; --i) {
deba@2508
  2696
	std::vector<bool> forbidden(5, false);
deba@2508
  2697
	for (OutEdgeIt e(_ugraph, order[i]); e != INVALID; ++e) {
deba@2508
  2698
	  Node t = _ugraph.runningNode(e); 
deba@2508
  2699
	  if (_color_map[t] != -1) {
deba@2508
  2700
	    forbidden[_color_map[t]] = true;
deba@2508
  2701
	  }
deba@2508
  2702
	}
deba@2508
  2703
	for (int k = 0; k < 5; ++k) {
deba@2508
  2704
	  if (!forbidden[k]) {
deba@2508
  2705
	    _color_map[order[i]] = k;
deba@2508
  2706
	    break;
deba@2508
  2707
	  }
deba@2508
  2708
	}
deba@2508
  2709
	if (_color_map[order[i]] == -1) {
deba@2508
  2710
	  kempeRecoloring(order[i], embedding);
deba@2508
  2711
	}
deba@2508
  2712
      }
deba@2508
  2713
    }
deba@2508
  2714
deba@2508
  2715
    /// \brief Calculates a coloring with at most five colors
deba@2508
  2716
    ///
deba@2508
  2717
    /// This function calculates a coloring with at most five
deba@2508
  2718
    /// colors. The worst case time complexity of this variant is
deba@2508
  2719
    /// quadratic in the size of the graph, but it most cases it does
deba@2508
  2720
    /// not have to use Kempe recoloring method, in this case it is
deba@2508
  2721
    /// equivalent with the runSixColoring() algorithm.
deba@2508
  2722
    /// \return %True when the graph is planar.
deba@2508
  2723
    bool runFiveColoring() {
deba@2508
  2724
      PlanarEmbedding<UGraph> pe(_ugraph);
deba@2508
  2725
      if (!pe.run()) return false;
deba@2508
  2726
      
deba@2508
  2727
      runFiveColoring(pe.embeddingMap());
deba@2508
  2728
      return true;
deba@2508
  2729
    }
deba@2508
  2730
deba@2508
  2731
  private:
deba@2508
  2732
    
deba@2508
  2733
    const UGraph& _ugraph;
deba@2508
  2734
    IndexMap _color_map;
deba@2508
  2735
    Palette _palette;
deba@2508
  2736
  };
deba@2508
  2737
deba@2480
  2738
}
deba@2480
  2739
deba@2480
  2740
#endif