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