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