lemon/planarity.h
author deba
Sun, 30 Sep 2007 19:14:33 +0000
changeset 2480 eecaeab41472
child 2481 ddb851e1481a
permissions -rw-r--r--
Planarity checking and embedding
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2007
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 #ifndef LEMON_PLANARITY_H
    19 #define LEMON_PLANARITY_H
    20 
    21 /// \ingroup graph_prop
    22 /// \file
    23 /// \brief Planarity checking, embedding
    24 
    25 #include <vector>
    26 #include <list>
    27 
    28 #include <lemon/dfs.h>
    29 #include <lemon/radix_sort.h>
    30 #include <lemon/maps.h>
    31 #include <lemon/path.h>
    32 
    33 
    34 namespace lemon {
    35 
    36   namespace _planarity_bits {
    37 
    38     template <typename UGraph>
    39     struct PlanarityVisitor : DfsVisitor<UGraph> {
    40 
    41       typedef typename UGraph::Node Node;
    42       typedef typename UGraph::Edge Edge;
    43 
    44       typedef typename UGraph::template NodeMap<Edge> PredMap;
    45 
    46       typedef typename UGraph::template UEdgeMap<bool> TreeMap;
    47 
    48       typedef typename UGraph::template NodeMap<int> OrderMap;
    49       typedef std::vector<Node> OrderList;
    50 
    51       typedef typename UGraph::template NodeMap<int> LowMap;
    52       typedef typename UGraph::template NodeMap<int> AncestorMap;
    53 
    54       PlanarityVisitor(const UGraph& ugraph,
    55 		       PredMap& pred_map, TreeMap& tree_map,
    56 		       OrderMap& order_map, OrderList& order_list,
    57 		       AncestorMap& ancestor_map, LowMap& low_map)
    58 	: _ugraph(ugraph), _pred_map(pred_map), _tree_map(tree_map),
    59 	  _order_map(order_map), _order_list(order_list),
    60 	  _ancestor_map(ancestor_map), _low_map(low_map) {}
    61       
    62       void reach(const Node& node) {
    63 	_order_map[node] = _order_list.size();
    64 	_low_map[node] = _order_list.size();
    65 	_ancestor_map[node] = _order_list.size();
    66 	_order_list.push_back(node);
    67       }
    68 
    69       void discover(const Edge& edge) {
    70 	Node source = _ugraph.source(edge);
    71 	Node target = _ugraph.target(edge);
    72 
    73 	_tree_map[edge] = true;
    74 	_pred_map[target] = edge;
    75       }
    76 
    77       void examine(const Edge& edge) {
    78 	Node source = _ugraph.source(edge);
    79 	Node target = _ugraph.target(edge);
    80 	
    81 	if (_order_map[target] < _order_map[source] && !_tree_map[edge]) {
    82 	  if (_low_map[source] > _order_map[target]) {
    83 	    _low_map[source] = _order_map[target];
    84 	  }
    85 	  if (_ancestor_map[source] > _order_map[target]) {
    86 	    _ancestor_map[source] = _order_map[target];
    87 	  }
    88 	}
    89       }
    90 
    91       void backtrack(const Edge& edge) {
    92 	Node source = _ugraph.source(edge);
    93 	Node target = _ugraph.target(edge);
    94 
    95 	if (_low_map[source] > _low_map[target]) {
    96 	  _low_map[source] = _low_map[target];
    97 	}
    98       }
    99 
   100       const UGraph& _ugraph;
   101       PredMap& _pred_map;
   102       TreeMap& _tree_map;
   103       OrderMap& _order_map;
   104       OrderList& _order_list;
   105       AncestorMap& _ancestor_map;
   106       LowMap& _low_map;
   107     };
   108 
   109     template <typename UGraph, bool embedding = true>
   110     struct NodeDataNode {
   111       int prev, next;
   112       int visited;
   113       typename UGraph::Edge first;
   114       bool inverted;
   115     };
   116 
   117     template <typename UGraph>
   118     struct NodeDataNode<UGraph, false> {
   119       int prev, next;
   120       int visited;
   121     };
   122 
   123     template <typename UGraph>
   124     struct ChildListNode {
   125       typedef typename UGraph::Node Node;
   126       Node first;
   127       Node prev, next;
   128     };
   129 
   130     template <typename UGraph>
   131     struct EdgeListNode {
   132       typename UGraph::Edge prev, next;
   133     };
   134 
   135   }
   136 
   137   /// \ingroup  graph_prop
   138   ///
   139   /// \brief Planarity checking of an undirected simple graph
   140   ///
   141   /// This class implements the Boyer-Myrvold algorithm for planar
   142   /// checking of an undirected graph. This class is a simplified
   143   /// version of the PlanarEmbedding algorithm class, and it does
   144   /// provide neither embedding nor kuratowski subdivisons.
   145   template <typename UGraph>
   146   class PlanarityChecking {
   147   private:
   148     
   149     UGRAPH_TYPEDEFS(typename UGraph)
   150       
   151     const UGraph& _ugraph;
   152 
   153   private:
   154 
   155     typedef typename UGraph::template NodeMap<Edge> PredMap;
   156     
   157     typedef typename UGraph::template UEdgeMap<bool> TreeMap;
   158 
   159     typedef typename UGraph::template NodeMap<int> OrderMap;
   160     typedef std::vector<Node> OrderList;
   161 
   162     typedef typename UGraph::template NodeMap<int> LowMap;
   163     typedef typename UGraph::template NodeMap<int> AncestorMap;
   164 
   165     typedef _planarity_bits::NodeDataNode<UGraph> NodeDataNode;
   166     typedef std::vector<NodeDataNode> NodeData;
   167     
   168     typedef _planarity_bits::ChildListNode<UGraph> ChildListNode;
   169     typedef typename UGraph::template NodeMap<ChildListNode> ChildLists;
   170 
   171     typedef typename UGraph::template NodeMap<std::list<int> > MergeRoots;
   172  
   173     typedef typename UGraph::template NodeMap<bool> EmbedEdge;
   174 
   175   public:
   176 
   177     /// \brief Constructor
   178     ///
   179     /// \warining The graph should be simple, i.e. parallel and loop edge
   180     /// free.
   181     PlanarityChecking(const UGraph& ugraph) : _ugraph(ugraph) {}
   182 
   183     /// \brief Runs the algorithm.
   184     ///
   185     /// Runs the algorithm.  
   186     /// \param kuratowski If the parameter is false, then the
   187     /// algorithm does not calculate the isolate Kuratowski
   188     /// subdivisions.
   189     /// \return %True when the graph is planar.
   190     bool run(bool kuratowski = true) {
   191       typedef _planarity_bits::PlanarityVisitor<UGraph> Visitor;
   192 
   193       PredMap pred_map(_ugraph, INVALID);
   194       TreeMap tree_map(_ugraph, false);
   195 
   196       OrderMap order_map(_ugraph, -1);
   197       OrderList order_list;
   198 
   199       AncestorMap ancestor_map(_ugraph, -1);
   200       LowMap low_map(_ugraph, -1);
   201 
   202       Visitor visitor(_ugraph, pred_map, tree_map,
   203 		      order_map, order_list, ancestor_map, low_map);
   204       DfsVisit<UGraph, Visitor> visit(_ugraph, visitor);
   205       visit.run();
   206 
   207       ChildLists child_lists(_ugraph);
   208       createChildLists(tree_map, order_map, low_map, child_lists);
   209 
   210       NodeData node_data(2 * order_list.size());
   211       
   212       EmbedEdge embed_edge(_ugraph, false);
   213 
   214       MergeRoots merge_roots(_ugraph);
   215       
   216       for (int i = order_list.size() - 1; i >= 0; --i) {
   217 
   218 	Node node = order_list[i];
   219 
   220 	Node source = node;
   221 	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
   222 	  Node target = _ugraph.target(e);
   223 	  
   224 	  if (order_map[source] < order_map[target] && tree_map[e]) {
   225 	    initFace(target, node_data, pred_map, order_map, order_list);
   226 	  }
   227 	}
   228 	
   229 	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
   230 	  Node target = _ugraph.target(e);
   231 	  
   232 	  if (order_map[source] < order_map[target] && !tree_map[e]) {
   233 	    embed_edge[target] = true;
   234 	    walkUp(target, source, i, pred_map, low_map,
   235 		   order_map, order_list, node_data, merge_roots);
   236 	  }
   237 	}
   238 
   239 	for (typename MergeRoots::Value::iterator it = 
   240 	       merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
   241 	  int rn = *it;
   242 	  walkDown(rn, i, node_data, order_list, child_lists, 
   243 		   ancestor_map, low_map, embed_edge, merge_roots);
   244 	}
   245 	merge_roots[node].clear();
   246 	
   247 	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
   248 	  Node target = _ugraph.target(e);
   249 	  
   250 	  if (order_map[source] < order_map[target] && !tree_map[e]) {
   251 	    if (embed_edge[target]) {
   252 	      return false;
   253 	    }
   254 	  }
   255 	}
   256       }
   257 
   258       return true;
   259     }
   260     
   261   private:
   262 
   263     void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
   264 			  const LowMap& low_map, ChildLists& child_lists) {
   265 
   266       for (NodeIt n(_ugraph); n != INVALID; ++n) {
   267 	Node source = n;
   268 	
   269 	std::vector<Node> targets;  
   270 	for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
   271 	  Node target = _ugraph.target(e);
   272 
   273 	  if (order_map[source] < order_map[target] && tree_map[e]) {
   274 	    targets.push_back(target);
   275 	  }
   276 	}	
   277 
   278 	if (targets.size() == 0) {
   279 	  child_lists[source].first = INVALID;
   280 	} else if (targets.size() == 1) {
   281 	  child_lists[source].first = targets[0];
   282 	  child_lists[targets[0]].prev = INVALID;
   283 	  child_lists[targets[0]].next = INVALID;
   284 	} else {
   285 	  radixSort(targets.begin(), targets.end(), mapFunctor(low_map));
   286 	  for (int i = 1; i < int(targets.size()); ++i) {
   287 	    child_lists[targets[i]].prev = targets[i - 1];
   288 	    child_lists[targets[i - 1]].next = targets[i];
   289 	  }
   290 	  child_lists[targets.back()].next = INVALID; 
   291 	  child_lists[targets.front()].prev = INVALID;
   292 	  child_lists[source].first = targets.front();
   293 	}
   294       }
   295     }
   296 
   297     void walkUp(const Node& node, Node root, int rorder,
   298 		const PredMap& pred_map, const LowMap& low_map,
   299 		const OrderMap& order_map, const OrderList& order_list,
   300 		NodeData& node_data, MergeRoots& merge_roots) {
   301 
   302       int na, nb;
   303       bool da, db;
   304       
   305       na = nb = order_map[node];
   306       da = true; db = false;
   307       
   308       while (true) {
   309 	
   310 	if (node_data[na].visited == rorder) break;
   311 	if (node_data[nb].visited == rorder) break;
   312 
   313 	node_data[na].visited = rorder;
   314 	node_data[nb].visited = rorder;
   315 
   316 	int rn = -1;
   317 
   318 	if (na >= int(order_list.size())) {
   319 	  rn = na;
   320 	} else if (nb >= int(order_list.size())) {
   321 	  rn = nb;
   322 	}
   323 
   324 	if (rn == -1) {
   325 	  int nn;
   326 	  
   327 	  nn = da ? node_data[na].prev : node_data[na].next;
   328 	  da = node_data[nn].prev != na;
   329 	  na = nn;
   330 	  
   331 	  nn = db ? node_data[nb].prev : node_data[nb].next;
   332 	  db = node_data[nn].prev != nb;
   333 	  nb = nn;
   334 
   335 	} else {
   336 
   337 	  Node rep = order_list[rn - order_list.size()];
   338 	  Node parent = _ugraph.source(pred_map[rep]);
   339 
   340 	  if (low_map[rep] < rorder) {
   341 	    merge_roots[parent].push_back(rn);
   342 	  } else {
   343 	    merge_roots[parent].push_front(rn);
   344 	  }
   345 	  
   346 	  if (parent != root) {  
   347 	    na = nb = order_map[parent];
   348 	    da = true; db = false;
   349 	  } else {
   350 	    break;
   351 	  }
   352 	}	
   353       }
   354     }
   355 
   356     void walkDown(int rn, int rorder, NodeData& node_data,
   357 		  OrderList& order_list, ChildLists& child_lists,
   358 		  AncestorMap& ancestor_map, LowMap& low_map,
   359 		  EmbedEdge& embed_edge, MergeRoots& merge_roots) {
   360 
   361       std::vector<std::pair<int, bool> > merge_stack;
   362 
   363       for (int di = 0; di < 2; ++di) {
   364 	bool rd = di == 0;
   365 	int pn = rn;
   366 	int n = rd ? node_data[rn].next : node_data[rn].prev;
   367 	
   368 	while (n != rn) {
   369 	  
   370 	  Node node = order_list[n];
   371 	  
   372 	  if (embed_edge[node]) {
   373 
   374 	    // Merging components on the critical path
   375 	    while (!merge_stack.empty()) {
   376 
   377 	      // Component root
   378 	      int cn = merge_stack.back().first;
   379 	      bool cd = merge_stack.back().second;
   380 	      merge_stack.pop_back();
   381 
   382 	      // Parent of component
   383 	      int dn = merge_stack.back().first;
   384 	      bool dd = merge_stack.back().second;
   385 	      merge_stack.pop_back();
   386 
   387 	      Node parent = order_list[dn];
   388 
   389 	      // Erasing from merge_roots
   390 	      merge_roots[parent].pop_front();
   391 	      
   392 	      Node child = order_list[cn - order_list.size()];
   393 
   394 	      // Erasing from child_lists
   395 	      if (child_lists[child].prev != INVALID) {
   396 		child_lists[child_lists[child].prev].next =
   397 		  child_lists[child].next;
   398 	      } else {
   399 		child_lists[parent].first = child_lists[child].next;
   400 	      }
   401 	      
   402 	      if (child_lists[child].next != INVALID) {
   403 		child_lists[child_lists[child].next].prev =
   404 		  child_lists[child].prev;
   405 	      }
   406 	      
   407 	      // Merging external faces
   408 	      {
   409 		int en = cn;
   410 		cn = cd ? node_data[cn].prev : node_data[cn].next;
   411 		cd = node_data[cn].next == en;
   412 
   413 	      }
   414 
   415 	      if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
   416 	      if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
   417 
   418 	    }
   419 
   420 	    bool d = pn == node_data[n].prev;
   421 
   422 	    if (node_data[n].prev == node_data[n].next && 
   423 		node_data[n].inverted) {
   424 	      d = !d;
   425 	    }
   426 
   427 	    // Embedding edge into external face
   428 	    if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
   429 	    if (d) node_data[n].prev = rn; else node_data[n].next = rn;
   430 	    pn = rn;
   431 
   432 	    embed_edge[order_list[n]] = false;
   433 	  }
   434 
   435 	  if (!merge_roots[node].empty()) {
   436 
   437 	    bool d = pn == node_data[n].prev;
   438 
   439 	    merge_stack.push_back(std::make_pair(n, d));
   440 
   441 	    int rn = merge_roots[node].front();
   442 	    
   443 	    int xn = node_data[rn].next;
   444 	    Node xnode = order_list[xn];
   445 	    
   446 	    int yn = node_data[rn].prev;
   447 	    Node ynode = order_list[yn];
   448 	    
   449 	    bool rd;
   450 	    if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
   451 	      rd = true;
   452 	    } else if (!external(ynode, rorder, child_lists, 
   453 				 ancestor_map, low_map)) {
   454 	      rd = false;
   455 	    } else if (pertinent(xnode, embed_edge, merge_roots)) {
   456 	      rd = true;
   457 	    } else {
   458 	      rd = false;
   459 	    }
   460 	    
   461 	    merge_stack.push_back(std::make_pair(rn, rd));
   462 	    
   463 	    pn = rn;
   464 	    n = rd ? xn : yn;	      
   465 	    	    
   466 	  } else if (!external(node, rorder, child_lists,
   467 			       ancestor_map, low_map)) {
   468 	    int nn = (node_data[n].next != pn ? 
   469 		      node_data[n].next : node_data[n].prev);
   470 
   471 	    bool nd = n == node_data[nn].prev;
   472 
   473 	    if (nd) node_data[nn].prev = pn;
   474 	    else node_data[nn].next = pn; 
   475 
   476 	    if (n == node_data[pn].prev) node_data[pn].prev = nn;
   477 	    else node_data[pn].next = nn;
   478 
   479 	    node_data[nn].inverted = 
   480 	      (node_data[nn].prev == node_data[nn].next && nd != rd);
   481 
   482 	    n = nn;
   483 	  }
   484 	  else break;
   485 	  
   486 	}
   487 
   488 	if (!merge_stack.empty() || n == rn) {
   489 	  break;
   490 	}
   491       }
   492     }
   493 
   494     void initFace(const Node& node, NodeData& node_data, 
   495 		  const PredMap& pred_map, const OrderMap& order_map, 
   496 		  const OrderList& order_list) {
   497       int n = order_map[node];
   498       int rn = n + order_list.size();
   499       
   500       node_data[n].next = node_data[n].prev = rn;
   501       node_data[rn].next = node_data[rn].prev = n;
   502       
   503       node_data[n].visited = order_list.size();
   504       node_data[rn].visited = order_list.size();
   505       
   506     }
   507 
   508     bool external(const Node& node, int rorder,
   509 		  ChildLists& child_lists, AncestorMap& ancestor_map, 
   510 		  LowMap& low_map) {
   511       Node child = child_lists[node].first;
   512 
   513       if (child != INVALID) {
   514 	if (low_map[child] < rorder) return true;
   515       }
   516 
   517       if (ancestor_map[node] < rorder) return true;
   518 
   519       return false;
   520     }
   521 
   522     bool pertinent(const Node& node, const EmbedEdge& embed_edge,
   523 		   const MergeRoots& merge_roots) {
   524       return !merge_roots[node].empty() || embed_edge[node];
   525     }
   526 
   527   };
   528 
   529   /// \ingroup graph_prop
   530   ///
   531   /// \brief Planar embedding of an undirected simple graph
   532   ///
   533   /// This class implements the Boyer-Myrvold algorithm for planar
   534   /// embedding of an undirected graph. The planar embeding is an
   535   /// ordering of the outgoing edges in each node, which is a possible
   536   /// configuration to draw the graph in the plane. If there is not
   537   /// such ordering then the graph contains a \f$ K_5 \f$ (full graph
   538   /// with 5 nodes) or an \f$ K_{3,3} \f$ (complete bipartite graph on
   539   /// 3 ANode and 3 BNode) subdivision.
   540   ///
   541   /// The current implementation calculates an embedding or an
   542   /// Kuratowski subdivision if the graph is not planar. The running
   543   /// time of the algorithm is \f$ O(n) \f$.
   544   template <typename UGraph>
   545   class PlanarEmbedding {
   546   private:
   547     
   548     UGRAPH_TYPEDEFS(typename UGraph)
   549       
   550     const UGraph& _ugraph;
   551     typename UGraph::template EdgeMap<Edge> _embedding;
   552 
   553     typename UGraph::template UEdgeMap<bool> _kuratowski;
   554 
   555   private:
   556 
   557     typedef typename UGraph::template NodeMap<Edge> PredMap;
   558     
   559     typedef typename UGraph::template UEdgeMap<bool> TreeMap;
   560 
   561     typedef typename UGraph::template NodeMap<int> OrderMap;
   562     typedef std::vector<Node> OrderList;
   563 
   564     typedef typename UGraph::template NodeMap<int> LowMap;
   565     typedef typename UGraph::template NodeMap<int> AncestorMap;
   566 
   567     typedef _planarity_bits::NodeDataNode<UGraph> NodeDataNode;
   568     typedef std::vector<NodeDataNode> NodeData;
   569     
   570     typedef _planarity_bits::ChildListNode<UGraph> ChildListNode;
   571     typedef typename UGraph::template NodeMap<ChildListNode> ChildLists;
   572 
   573     typedef typename UGraph::template NodeMap<std::list<int> > MergeRoots;
   574  
   575     typedef typename UGraph::template NodeMap<Edge> EmbedEdge;
   576 
   577     typedef _planarity_bits::EdgeListNode<UGraph> EdgeListNode;
   578     typedef typename UGraph::template EdgeMap<EdgeListNode> EdgeLists;
   579 
   580     typedef typename UGraph::template NodeMap<bool> FlipMap;
   581 
   582     typedef typename UGraph::template NodeMap<int> TypeMap;
   583 
   584     enum IsolatorNodeType {
   585       HIGHX = 6, LOWX = 7,
   586       HIGHY = 8, LOWY = 9,
   587       ROOT = 10, PERTINENT = 11,
   588       INTERNAL = 12
   589     };
   590 
   591   public:
   592 
   593     /// \brief Constructor
   594     ///
   595     /// \warining The graph should be simple, i.e. parallel and loop edge
   596     /// free.
   597     PlanarEmbedding(const UGraph& ugraph)
   598       : _ugraph(ugraph), _embedding(_ugraph), _kuratowski(ugraph, false) {}
   599 
   600     /// \brief Runs the algorithm.
   601     ///
   602     /// Runs the algorithm.  
   603     /// \param kuratowski If the parameter is false, then the
   604     /// algorithm does not calculate the isolate Kuratowski
   605     /// subdivisions.
   606     ///\return %True when the graph is planar.
   607     bool run(bool kuratowski = true) {
   608       typedef _planarity_bits::PlanarityVisitor<UGraph> Visitor;
   609 
   610       PredMap pred_map(_ugraph, INVALID);
   611       TreeMap tree_map(_ugraph, false);
   612 
   613       OrderMap order_map(_ugraph, -1);
   614       OrderList order_list;
   615 
   616       AncestorMap ancestor_map(_ugraph, -1);
   617       LowMap low_map(_ugraph, -1);
   618 
   619       Visitor visitor(_ugraph, pred_map, tree_map,
   620 		      order_map, order_list, ancestor_map, low_map);
   621       DfsVisit<UGraph, Visitor> visit(_ugraph, visitor);
   622       visit.run();
   623 
   624       ChildLists child_lists(_ugraph);
   625       createChildLists(tree_map, order_map, low_map, child_lists);
   626 
   627       NodeData node_data(2 * order_list.size());
   628       
   629       EmbedEdge embed_edge(_ugraph, INVALID);
   630 
   631       MergeRoots merge_roots(_ugraph);
   632 
   633       EdgeLists edge_lists(_ugraph);
   634 
   635       FlipMap flip_map(_ugraph, false);
   636 
   637       for (int i = order_list.size() - 1; i >= 0; --i) {
   638 
   639 	Node node = order_list[i];
   640 
   641 	node_data[i].first = INVALID;
   642 	
   643 	Node source = node;
   644 	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
   645 	  Node target = _ugraph.target(e);
   646 	  
   647 	  if (order_map[source] < order_map[target] && tree_map[e]) {
   648 	    initFace(target, edge_lists, node_data,
   649 		      pred_map, order_map, order_list);
   650 	  }
   651 	}
   652 	
   653 	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
   654 	  Node target = _ugraph.target(e);
   655 	  
   656 	  if (order_map[source] < order_map[target] && !tree_map[e]) {
   657 	    embed_edge[target] = e;
   658 	    walkUp(target, source, i, pred_map, low_map,
   659 		   order_map, order_list, node_data, merge_roots);
   660 	  }
   661 	}
   662 
   663 	for (typename MergeRoots::Value::iterator it = 
   664 	       merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
   665 	  int rn = *it;
   666 	  walkDown(rn, i, node_data, edge_lists, flip_map, order_list, 
   667 		   child_lists, ancestor_map, low_map, embed_edge, merge_roots);
   668 	}
   669 	merge_roots[node].clear();
   670 	
   671 	for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
   672 	  Node target = _ugraph.target(e);
   673 	  
   674 	  if (order_map[source] < order_map[target] && !tree_map[e]) {
   675 	    if (embed_edge[target] != INVALID) {
   676 	      if (kuratowski) {
   677 		isolateKuratowski(e, node_data, edge_lists, flip_map,
   678 				  order_map, order_list, pred_map, child_lists,
   679 				  ancestor_map, low_map, 
   680 				  embed_edge, merge_roots);
   681 	      }
   682 	      return false;
   683 	    }
   684 	  }
   685 	}
   686       }
   687 
   688       for (int i = 0; i < int(order_list.size()); ++i) {
   689 
   690 	mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
   691 			    child_lists, edge_lists);
   692 	storeEmbedding(order_list[i], node_data, order_map, pred_map,
   693 		       edge_lists, flip_map);
   694       }
   695 
   696       return true;
   697     }
   698 
   699     /// \brief Gives back the successor of an edge
   700     ///
   701     /// Gives back the successor of an edge. This function makes
   702     /// possible to query the cyclic order of the outgoing edges from
   703     /// a node.
   704     Edge next(const Edge& edge) const {
   705       return _embedding[edge];
   706     }
   707 
   708     /// \brief Gives back true when the undirected edge is in the
   709     /// kuratowski subdivision
   710     ///
   711     /// Gives back true when the undirected edge is in the kuratowski
   712     /// subdivision
   713     bool kuratowski(const UEdge& uedge) {
   714       return _kuratowski[uedge];
   715     }
   716 
   717   private:
   718 
   719     void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
   720 			  const LowMap& low_map, ChildLists& child_lists) {
   721 
   722       for (NodeIt n(_ugraph); n != INVALID; ++n) {
   723 	Node source = n;
   724 	
   725 	std::vector<Node> targets;  
   726 	for (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
   727 	  Node target = _ugraph.target(e);
   728 
   729 	  if (order_map[source] < order_map[target] && tree_map[e]) {
   730 	    targets.push_back(target);
   731 	  }
   732 	}	
   733 
   734 	if (targets.size() == 0) {
   735 	  child_lists[source].first = INVALID;
   736 	} else if (targets.size() == 1) {
   737 	  child_lists[source].first = targets[0];
   738 	  child_lists[targets[0]].prev = INVALID;
   739 	  child_lists[targets[0]].next = INVALID;
   740 	} else {
   741 	  radixSort(targets.begin(), targets.end(), mapFunctor(low_map));
   742 	  for (int i = 1; i < int(targets.size()); ++i) {
   743 	    child_lists[targets[i]].prev = targets[i - 1];
   744 	    child_lists[targets[i - 1]].next = targets[i];
   745 	  }
   746 	  child_lists[targets.back()].next = INVALID; 
   747 	  child_lists[targets.front()].prev = INVALID;
   748 	  child_lists[source].first = targets.front();
   749 	}
   750       }
   751     }
   752 
   753     void walkUp(const Node& node, Node root, int rorder,
   754 		const PredMap& pred_map, const LowMap& low_map,
   755 		const OrderMap& order_map, const OrderList& order_list,
   756 		NodeData& node_data, MergeRoots& merge_roots) {
   757 
   758       int na, nb;
   759       bool da, db;
   760       
   761       na = nb = order_map[node];
   762       da = true; db = false;
   763       
   764       while (true) {
   765 	
   766 	if (node_data[na].visited == rorder) break;
   767 	if (node_data[nb].visited == rorder) break;
   768 
   769 	node_data[na].visited = rorder;
   770 	node_data[nb].visited = rorder;
   771 
   772 	int rn = -1;
   773 
   774 	if (na >= int(order_list.size())) {
   775 	  rn = na;
   776 	} else if (nb >= int(order_list.size())) {
   777 	  rn = nb;
   778 	}
   779 
   780 	if (rn == -1) {
   781 	  int nn;
   782 	  
   783 	  nn = da ? node_data[na].prev : node_data[na].next;
   784 	  da = node_data[nn].prev != na;
   785 	  na = nn;
   786 	  
   787 	  nn = db ? node_data[nb].prev : node_data[nb].next;
   788 	  db = node_data[nn].prev != nb;
   789 	  nb = nn;
   790 
   791 	} else {
   792 
   793 	  Node rep = order_list[rn - order_list.size()];
   794 	  Node parent = _ugraph.source(pred_map[rep]);
   795 
   796 	  if (low_map[rep] < rorder) {
   797 	    merge_roots[parent].push_back(rn);
   798 	  } else {
   799 	    merge_roots[parent].push_front(rn);
   800 	  }
   801 	  
   802 	  if (parent != root) {  
   803 	    na = nb = order_map[parent];
   804 	    da = true; db = false;
   805 	  } else {
   806 	    break;
   807 	  }
   808 	}	
   809       }
   810     }
   811 
   812     void walkDown(int rn, int rorder, NodeData& node_data,
   813 		  EdgeLists& edge_lists, FlipMap& flip_map, 
   814 		  OrderList& order_list, ChildLists& child_lists,
   815 		  AncestorMap& ancestor_map, LowMap& low_map,
   816 		  EmbedEdge& embed_edge, MergeRoots& merge_roots) {
   817 
   818       std::vector<std::pair<int, bool> > merge_stack;
   819 
   820       for (int di = 0; di < 2; ++di) {
   821 	bool rd = di == 0;
   822 	int pn = rn;
   823 	int n = rd ? node_data[rn].next : node_data[rn].prev;
   824 	
   825 	while (n != rn) {
   826 	  
   827 	  Node node = order_list[n];
   828 	  
   829 	  if (embed_edge[node] != INVALID) {
   830 
   831 	    // Merging components on the critical path
   832 	    while (!merge_stack.empty()) {
   833 
   834 	      // Component root
   835 	      int cn = merge_stack.back().first;
   836 	      bool cd = merge_stack.back().second;
   837 	      merge_stack.pop_back();
   838 
   839 	      // Parent of component
   840 	      int dn = merge_stack.back().first;
   841 	      bool dd = merge_stack.back().second;
   842 	      merge_stack.pop_back();
   843 
   844 	      Node parent = order_list[dn];
   845 
   846 	      // Erasing from merge_roots
   847 	      merge_roots[parent].pop_front();
   848 	      
   849 	      Node child = order_list[cn - order_list.size()];
   850 
   851 	      // Erasing from child_lists
   852 	      if (child_lists[child].prev != INVALID) {
   853 		child_lists[child_lists[child].prev].next =
   854 		  child_lists[child].next;
   855 	      } else {
   856 		child_lists[parent].first = child_lists[child].next;
   857 	      }
   858 	      
   859 	      if (child_lists[child].next != INVALID) {
   860 		child_lists[child_lists[child].next].prev =
   861 		  child_lists[child].prev;
   862 	      }
   863 
   864 	      // Merging edges + flipping
   865 	      Edge de = node_data[dn].first;
   866 	      Edge ce = node_data[cn].first;
   867 
   868 	      flip_map[order_list[cn - order_list.size()]] = cd != dd;
   869 	      if (cd != dd) {
   870 		std::swap(edge_lists[ce].prev, edge_lists[ce].next);
   871 		ce = edge_lists[ce].prev;
   872 		std::swap(edge_lists[ce].prev, edge_lists[ce].next);
   873 	      }
   874 
   875 	      {
   876 		Edge dne = edge_lists[de].next; 
   877 		Edge cne = edge_lists[ce].next; 
   878 
   879 		edge_lists[de].next = cne;
   880 		edge_lists[ce].next = dne;
   881 	      
   882 		edge_lists[dne].prev = ce;
   883 		edge_lists[cne].prev = de;
   884 	      }
   885 	      	      
   886 	      if (dd) {
   887 		node_data[dn].first = ce;
   888 	      }
   889 	      
   890 	      // Merging external faces
   891 	      {
   892 		int en = cn;
   893 		cn = cd ? node_data[cn].prev : node_data[cn].next;
   894 		cd = node_data[cn].next == en;
   895 
   896  		if (node_data[cn].prev == node_data[cn].next && 
   897 		    node_data[cn].inverted) {
   898  		  cd = !cd;
   899  		}
   900 	      }
   901 
   902 	      if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
   903 	      if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
   904 
   905 	    }
   906 
   907 	    bool d = pn == node_data[n].prev;
   908 
   909 	    if (node_data[n].prev == node_data[n].next && 
   910 		node_data[n].inverted) {
   911 	      d = !d;
   912 	    }
   913 
   914 	    // Add new edge
   915 	    {
   916 	      Edge edge = embed_edge[node];
   917 	      Edge re = node_data[rn].first;
   918 
   919 	      edge_lists[edge_lists[re].next].prev = edge;
   920 	      edge_lists[edge].next = edge_lists[re].next;
   921 	      edge_lists[edge].prev = re;
   922 	      edge_lists[re].next = edge;
   923 
   924 	      if (!rd) {
   925 		node_data[rn].first = edge;
   926 	      }
   927 
   928 	      Edge rev = _ugraph.oppositeEdge(edge);
   929 	      Edge e = node_data[n].first;
   930 
   931 	      edge_lists[edge_lists[e].next].prev = rev;
   932 	      edge_lists[rev].next = edge_lists[e].next;
   933 	      edge_lists[rev].prev = e;
   934 	      edge_lists[e].next = rev;
   935 
   936 	      if (d) {
   937 		node_data[n].first = rev;
   938 	      }
   939 	      
   940 	    }
   941 
   942 	    // Embedding edge into external face
   943 	    if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
   944 	    if (d) node_data[n].prev = rn; else node_data[n].next = rn;
   945 	    pn = rn;
   946 
   947 	    embed_edge[order_list[n]] = INVALID;
   948 	  }
   949 
   950 	  if (!merge_roots[node].empty()) {
   951 
   952 	    bool d = pn == node_data[n].prev;
   953 	    if (node_data[n].prev == node_data[n].next && 
   954 		node_data[n].inverted) {
   955 	      d = !d;
   956 	    }
   957 
   958 	    merge_stack.push_back(std::make_pair(n, d));
   959 
   960 	    int rn = merge_roots[node].front();
   961 	    
   962 	    int xn = node_data[rn].next;
   963 	    Node xnode = order_list[xn];
   964 	    
   965 	    int yn = node_data[rn].prev;
   966 	    Node ynode = order_list[yn];
   967 	    
   968 	    bool rd;
   969 	    if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
   970 	      rd = true;
   971 	    } else if (!external(ynode, rorder, child_lists, 
   972 				 ancestor_map, low_map)) {
   973 	      rd = false;
   974 	    } else if (pertinent(xnode, embed_edge, merge_roots)) {
   975 	      rd = true;
   976 	    } else {
   977 	      rd = false;
   978 	    }
   979 	    
   980 	    merge_stack.push_back(std::make_pair(rn, rd));
   981 	    
   982 	    pn = rn;
   983 	    n = rd ? xn : yn;	      
   984 	    	    
   985 	  } else if (!external(node, rorder, child_lists,
   986 			       ancestor_map, low_map)) {
   987 	    int nn = (node_data[n].next != pn ? 
   988 		      node_data[n].next : node_data[n].prev);
   989 
   990 	    bool nd = n == node_data[nn].prev;
   991 
   992 	    if (nd) node_data[nn].prev = pn;
   993 	    else node_data[nn].next = pn; 
   994 
   995 	    if (n == node_data[pn].prev) node_data[pn].prev = nn;
   996 	    else node_data[pn].next = nn;
   997 
   998 	    node_data[nn].inverted = 
   999 	      (node_data[nn].prev == node_data[nn].next && nd != rd);
  1000 
  1001 	    n = nn;
  1002 	  }
  1003 	  else break;
  1004 	  
  1005 	}
  1006 
  1007 	if (!merge_stack.empty() || n == rn) {
  1008 	  break;
  1009 	}
  1010       }
  1011     }
  1012 
  1013     void initFace(const Node& node, EdgeLists& edge_lists,
  1014 		   NodeData& node_data, const PredMap& pred_map,
  1015 		   const OrderMap& order_map, const OrderList& order_list) {
  1016       int n = order_map[node];
  1017       int rn = n + order_list.size();
  1018       
  1019       node_data[n].next = node_data[n].prev = rn;
  1020       node_data[rn].next = node_data[rn].prev = n;
  1021       
  1022       node_data[n].visited = order_list.size();
  1023       node_data[rn].visited = order_list.size();
  1024 
  1025       node_data[n].inverted = false;
  1026       node_data[rn].inverted = false;
  1027 
  1028       Edge edge = pred_map[node];
  1029       Edge rev = _ugraph.oppositeEdge(edge);
  1030 
  1031       node_data[rn].first = edge;
  1032       node_data[n].first = rev;
  1033 
  1034       edge_lists[edge].prev = edge;
  1035       edge_lists[edge].next = edge;
  1036 
  1037       edge_lists[rev].prev = rev;
  1038       edge_lists[rev].next = rev;
  1039 
  1040     }
  1041 
  1042     void mergeRemainingFaces(const Node& node, NodeData& node_data,
  1043 			     OrderList& order_list, OrderMap& order_map,
  1044 			     ChildLists& child_lists, EdgeLists& edge_lists) {
  1045       while (child_lists[node].first != INVALID) {
  1046 	int dd = order_map[node];
  1047 	Node child = child_lists[node].first; 
  1048 	int cd = order_map[child] + order_list.size();
  1049 	child_lists[node].first = child_lists[child].next;
  1050 
  1051 	Edge de = node_data[dd].first;
  1052 	Edge ce = node_data[cd].first;
  1053 
  1054 	if (de != INVALID) {
  1055 	  Edge dne = edge_lists[de].next; 
  1056 	  Edge cne = edge_lists[ce].next; 
  1057 	  
  1058 	  edge_lists[de].next = cne;
  1059 	  edge_lists[ce].next = dne;
  1060 	  
  1061 	  edge_lists[dne].prev = ce;
  1062 	  edge_lists[cne].prev = de;
  1063 	}
  1064 	
  1065 	node_data[dd].first = ce;
  1066 
  1067       }
  1068     }
  1069 
  1070     void storeEmbedding(const Node& node, NodeData& node_data,
  1071 			OrderMap& order_map, PredMap& pred_map,
  1072 			EdgeLists& edge_lists, FlipMap& flip_map) {
  1073 
  1074       if (node_data[order_map[node]].first == INVALID) return;
  1075 
  1076       if (pred_map[node] != INVALID) {
  1077 	Node source = _ugraph.source(pred_map[node]);
  1078 	flip_map[node] = flip_map[node] != flip_map[source];
  1079       }
  1080       
  1081       Edge first = node_data[order_map[node]].first;
  1082       Edge prev = first;
  1083 
  1084       Edge edge = flip_map[node] ?
  1085 	edge_lists[prev].prev : edge_lists[prev].next;
  1086 
  1087       _embedding[prev] = edge;
  1088       
  1089       while (edge != first) {
  1090 	Edge next = edge_lists[edge].prev == prev ?
  1091 	  edge_lists[edge].next : edge_lists[edge].prev;
  1092 	prev = edge; edge = next;
  1093 	_embedding[prev] = edge;
  1094       }
  1095     }
  1096 
  1097 
  1098     bool external(const Node& node, int rorder,
  1099 		  ChildLists& child_lists, AncestorMap& ancestor_map, 
  1100 		  LowMap& low_map) {
  1101       Node child = child_lists[node].first;
  1102 
  1103       if (child != INVALID) {
  1104 	if (low_map[child] < rorder) return true;
  1105       }
  1106 
  1107       if (ancestor_map[node] < rorder) return true;
  1108 
  1109       return false;
  1110     }
  1111 
  1112     bool pertinent(const Node& node, const EmbedEdge& embed_edge,
  1113 		   const MergeRoots& merge_roots) {
  1114       return !merge_roots[node].empty() || embed_edge[node] != INVALID;
  1115     }
  1116 
  1117     int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
  1118 		 AncestorMap& ancestor_map, LowMap& low_map) {
  1119       int low_point;
  1120 
  1121       Node child = child_lists[node].first;
  1122 
  1123       if (child != INVALID) {
  1124 	low_point = low_map[child];
  1125       } else {
  1126 	low_point = order_map[node];
  1127       }
  1128 
  1129       if (low_point > ancestor_map[node]) {
  1130 	low_point = ancestor_map[node];
  1131       }
  1132 
  1133       return low_point;
  1134     }
  1135 
  1136     int findComponentRoot(Node root, Node node, ChildLists& child_lists, 
  1137 			  OrderMap& order_map, OrderList& order_list) {
  1138 
  1139       int order = order_map[root];
  1140       int norder = order_map[node];
  1141 
  1142       Node child = child_lists[root].first;
  1143       while (child != INVALID) {
  1144 	int corder = order_map[child];
  1145 	if (corder > order && corder < norder) {
  1146 	  order = corder;
  1147 	}
  1148 	child = child_lists[child].next;
  1149       }
  1150       return order + order_list.size();
  1151     }
  1152 
  1153     Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
  1154 		       EmbedEdge& embed_edge, MergeRoots& merge_roots) {
  1155       Node wnode =_ugraph.target(node_data[order_map[node]].first);
  1156       while (!pertinent(wnode, embed_edge, merge_roots)) {
  1157 	wnode = _ugraph.target(node_data[order_map[wnode]].first);
  1158       }
  1159       return wnode;
  1160     }
  1161 
  1162 
  1163     Node findExternal(Node node, int rorder, OrderMap& order_map, 
  1164 		      ChildLists& child_lists, AncestorMap& ancestor_map,
  1165 		      LowMap& low_map, NodeData& node_data) {
  1166       Node wnode =_ugraph.target(node_data[order_map[node]].first);
  1167       while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
  1168 	wnode = _ugraph.target(node_data[order_map[wnode]].first);
  1169       }
  1170       return wnode;
  1171     }
  1172 
  1173     void markCommonPath(Node node, int rorder, Node& wnode, Node& znode, 
  1174 			OrderList& order_list, OrderMap& order_map, 
  1175 			NodeData& node_data, EdgeLists& edge_lists, 
  1176 			EmbedEdge& embed_edge, MergeRoots& merge_roots, 
  1177 			ChildLists& child_lists, AncestorMap& ancestor_map, 
  1178 			LowMap& low_map) {
  1179       
  1180       Node cnode = node;
  1181       Node pred = INVALID;
  1182       
  1183       while (true) {
  1184 
  1185 	bool pert = pertinent(cnode, embed_edge, merge_roots);
  1186 	bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
  1187 
  1188 	if (pert && ext) {
  1189 	  if (!merge_roots[cnode].empty()) {
  1190 	    int cn = merge_roots[cnode].back();
  1191 	    
  1192 	    if (low_map[order_list[cn - order_list.size()]] < rorder) {
  1193 	      Edge edge = node_data[cn].first;
  1194 	      _kuratowski.set(edge, true);
  1195 	      
  1196 	      pred = cnode;
  1197 	      cnode = _ugraph.target(edge);
  1198 	    
  1199 	      continue;
  1200 	    }
  1201 	  }
  1202 	  wnode = znode = cnode;
  1203 	  return;
  1204 
  1205 	} else if (pert) {
  1206 	  wnode = cnode;
  1207 	  
  1208 	  while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
  1209 	    Edge edge = node_data[order_map[cnode]].first;
  1210 	  
  1211 	    if (_ugraph.target(edge) == pred) {
  1212 	      edge = edge_lists[edge].next;
  1213 	    }
  1214 	    _kuratowski.set(edge, true);
  1215 	    
  1216 	    Node next = _ugraph.target(edge);
  1217 	    pred = cnode; cnode = next;
  1218 	  }
  1219 	  
  1220 	  znode = cnode;
  1221 	  return;
  1222 
  1223 	} else if (ext) {
  1224 	  znode = cnode;
  1225 	  
  1226 	  while (!pertinent(cnode, embed_edge, merge_roots)) {
  1227 	    Edge edge = node_data[order_map[cnode]].first;
  1228 	  
  1229 	    if (_ugraph.target(edge) == pred) {
  1230 	      edge = edge_lists[edge].next;
  1231 	    }
  1232 	    _kuratowski.set(edge, true);
  1233 	    
  1234 	    Node next = _ugraph.target(edge);
  1235 	    pred = cnode; cnode = next;
  1236 	  }
  1237 	  
  1238 	  wnode = cnode;
  1239 	  return;
  1240 	  
  1241 	} else {
  1242 	  Edge edge = node_data[order_map[cnode]].first;
  1243 	  
  1244 	  if (_ugraph.target(edge) == pred) {
  1245 	    edge = edge_lists[edge].next;
  1246 	  }
  1247 	  _kuratowski.set(edge, true);
  1248 
  1249 	  Node next = _ugraph.target(edge);
  1250 	  pred = cnode; cnode = next;
  1251 	}
  1252 	
  1253       }
  1254 
  1255     }
  1256 
  1257     void orientComponent(Node root, int rn, OrderMap& order_map,
  1258 			 PredMap& pred_map, NodeData& node_data, 
  1259 			 EdgeLists& edge_lists, FlipMap& flip_map, 
  1260 			 TypeMap& type_map) {
  1261       node_data[order_map[root]].first = node_data[rn].first;
  1262       type_map[root] = 1;
  1263 
  1264       std::vector<Node> st, qu;
  1265 
  1266       st.push_back(root);
  1267       while (!st.empty()) {
  1268 	Node node = st.back();
  1269 	st.pop_back();
  1270 	qu.push_back(node);
  1271 	
  1272 	Edge edge = node_data[order_map[node]].first;
  1273 	
  1274 	if (type_map[_ugraph.target(edge)] == 0) {
  1275 	  st.push_back(_ugraph.target(edge));
  1276 	  type_map[_ugraph.target(edge)] = 1;
  1277 	} 
  1278 	
  1279 	Edge last = edge, pred = edge;
  1280 	edge = edge_lists[edge].next;
  1281 	while (edge != last) {
  1282 
  1283 	  if (type_map[_ugraph.target(edge)] == 0) {
  1284 	    st.push_back(_ugraph.target(edge));
  1285 	    type_map[_ugraph.target(edge)] = 1;
  1286 	  } 
  1287 	  
  1288 	  Edge next = edge_lists[edge].next != pred ? 
  1289 	    edge_lists[edge].next : edge_lists[edge].prev;
  1290 	  pred = edge; edge = next;
  1291 	}
  1292 
  1293       }
  1294 
  1295       type_map[root] = 2;
  1296       flip_map[root] = false;
  1297 
  1298       for (int i = 1; i < int(qu.size()); ++i) {
  1299 
  1300 	Node node = qu[i];
  1301 
  1302 	while (type_map[node] != 2) {
  1303 	  st.push_back(node);
  1304 	  type_map[node] = 2;
  1305 	  node = _ugraph.source(pred_map[node]);
  1306 	}
  1307 
  1308 	bool flip = flip_map[node];
  1309 
  1310 	while (!st.empty()) {
  1311 	  node = st.back();
  1312 	  st.pop_back();
  1313 	  
  1314 	  flip_map[node] = flip != flip_map[node];
  1315 	  flip = flip_map[node];
  1316 
  1317 	  if (flip) {
  1318 	    Edge edge = node_data[order_map[node]].first;
  1319 	    std::swap(edge_lists[edge].prev, edge_lists[edge].next);
  1320 	    edge = edge_lists[edge].prev;
  1321 	    std::swap(edge_lists[edge].prev, edge_lists[edge].next);
  1322 	    node_data[order_map[node]].first = edge;
  1323 	  }
  1324 	}
  1325       }
  1326 
  1327       for (int i = 0; i < int(qu.size()); ++i) {
  1328 
  1329 	Edge edge = node_data[order_map[qu[i]]].first;
  1330 	Edge last = edge, pred = edge;
  1331 
  1332 	edge = edge_lists[edge].next;
  1333 	while (edge != last) {
  1334 
  1335 	  if (edge_lists[edge].next == pred) {
  1336 	    std::swap(edge_lists[edge].next, edge_lists[edge].prev);
  1337 	  } 
  1338 	  pred = edge; edge = edge_lists[edge].next;
  1339 	}
  1340 	
  1341       }
  1342     }
  1343 
  1344     void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
  1345 		      OrderMap& order_map, NodeData& node_data, 
  1346 		      TypeMap& type_map) {
  1347       Node node = _ugraph.target(node_data[order_map[root]].first);
  1348 
  1349       while (node != ynode) {
  1350 	type_map[node] = HIGHY;
  1351 	node = _ugraph.target(node_data[order_map[node]].first);
  1352       }
  1353 
  1354       while (node != wnode) {
  1355 	type_map[node] = LOWY;
  1356 	node = _ugraph.target(node_data[order_map[node]].first);
  1357       }
  1358       
  1359       node = _ugraph.target(node_data[order_map[wnode]].first);
  1360       
  1361       while (node != xnode) {
  1362 	type_map[node] = LOWX;
  1363 	node = _ugraph.target(node_data[order_map[node]].first);
  1364       }
  1365       type_map[node] = LOWX;
  1366 
  1367       node = _ugraph.target(node_data[order_map[xnode]].first);
  1368       while (node != root) {
  1369 	type_map[node] = HIGHX;
  1370 	node = _ugraph.target(node_data[order_map[node]].first);
  1371       }
  1372 
  1373       type_map[wnode] = PERTINENT;
  1374       type_map[root] = ROOT;
  1375     }
  1376 
  1377     void findInternalPath(std::vector<Edge>& ipath,
  1378 			  Node wnode, Node root, TypeMap& type_map, 
  1379 			  OrderMap& order_map, NodeData& node_data, 
  1380 			  EdgeLists& edge_lists) {
  1381       std::vector<Edge> st;
  1382 
  1383       Node node = wnode;
  1384       
  1385       while (node != root) {
  1386 	Edge edge = edge_lists[node_data[order_map[node]].first].next;
  1387 	st.push_back(edge);
  1388 	node = _ugraph.target(edge);
  1389       }
  1390       
  1391       while (true) {
  1392 	Edge edge = st.back();
  1393 	if (type_map[_ugraph.target(edge)] == LOWX ||
  1394 	    type_map[_ugraph.target(edge)] == HIGHX) {
  1395 	  break;
  1396 	}
  1397 	if (type_map[_ugraph.target(edge)] == 2) {
  1398 	  type_map[_ugraph.target(edge)] = 3;
  1399 	  
  1400 	  edge = edge_lists[_ugraph.oppositeEdge(edge)].next;
  1401 	  st.push_back(edge);
  1402 	} else {
  1403 	  st.pop_back();
  1404 	  edge = edge_lists[edge].next;
  1405 	  
  1406 	  while (_ugraph.oppositeEdge(edge) == st.back()) {
  1407 	    edge = st.back();
  1408 	    st.pop_back();
  1409 	    edge = edge_lists[edge].next;
  1410 	  }
  1411 	  st.push_back(edge);
  1412 	}
  1413       }
  1414       
  1415       for (int i = 0; i < int(st.size()); ++i) {
  1416 	if (type_map[_ugraph.target(st[i])] != LOWY &&
  1417 	    type_map[_ugraph.target(st[i])] != HIGHY) {
  1418 	  for (; i < int(st.size()); ++i) {
  1419 	    ipath.push_back(st[i]);
  1420 	  }
  1421 	}
  1422       }
  1423     }
  1424 
  1425     void setInternalFlags(std::vector<Edge>& ipath, TypeMap& type_map) {
  1426       for (int i = 1; i < int(ipath.size()); ++i) {
  1427 	type_map[_ugraph.source(ipath[i])] = INTERNAL;
  1428       }
  1429     }
  1430 
  1431     void findPilePath(std::vector<Edge>& ppath,
  1432 		      Node root, TypeMap& type_map, OrderMap& order_map, 
  1433 		      NodeData& node_data, EdgeLists& edge_lists) {
  1434       std::vector<Edge> st;
  1435 
  1436       st.push_back(_ugraph.oppositeEdge(node_data[order_map[root]].first));
  1437       st.push_back(node_data[order_map[root]].first);
  1438       
  1439       while (st.size() > 1) {
  1440 	Edge edge = st.back();
  1441 	if (type_map[_ugraph.target(edge)] == INTERNAL) {
  1442 	  break;
  1443 	}
  1444 	if (type_map[_ugraph.target(edge)] == 3) {
  1445 	  type_map[_ugraph.target(edge)] = 4;
  1446 	  
  1447 	  edge = edge_lists[_ugraph.oppositeEdge(edge)].next;
  1448 	  st.push_back(edge);
  1449 	} else {
  1450 	  st.pop_back();
  1451 	  edge = edge_lists[edge].next;
  1452 	  
  1453 	  while (!st.empty() && _ugraph.oppositeEdge(edge) == st.back()) {
  1454 	    edge = st.back();
  1455 	    st.pop_back();
  1456 	    edge = edge_lists[edge].next;
  1457 	  }
  1458 	  st.push_back(edge);
  1459 	}
  1460       }
  1461       
  1462       for (int i = 1; i < int(st.size()); ++i) {
  1463 	ppath.push_back(st[i]);
  1464       }
  1465     }
  1466 
  1467 
  1468     int markExternalPath(Node node, OrderMap& order_map,
  1469 			 ChildLists& child_lists, PredMap& pred_map,
  1470 			 AncestorMap& ancestor_map, LowMap& low_map) {
  1471       int lp = lowPoint(node, order_map, child_lists,
  1472 			ancestor_map, low_map);
  1473       
  1474       if (ancestor_map[node] != lp) {
  1475 	node = child_lists[node].first;
  1476 	_kuratowski[pred_map[node]] = true;
  1477 
  1478 	while (ancestor_map[node] != lp) {
  1479 	  for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
  1480 	    Node tnode = _ugraph.target(e); 
  1481 	    if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
  1482 	      node = tnode;
  1483 	      _kuratowski[e] = true;
  1484 	      break;
  1485 	    }
  1486 	  }
  1487 	}
  1488       }
  1489 
  1490       for (OutEdgeIt e(_ugraph, node); e != INVALID; ++e) {
  1491 	if (order_map[_ugraph.target(e)] == lp) {
  1492 	  _kuratowski[e] = true;
  1493 	  break;
  1494 	}
  1495       }
  1496       
  1497       return lp;
  1498     }
  1499 
  1500     void markPertinentPath(Node node, OrderMap& order_map, 
  1501 			   NodeData& node_data, EdgeLists& edge_lists,
  1502 			   EmbedEdge& embed_edge, MergeRoots& merge_roots) {
  1503       while (embed_edge[node] == INVALID) {
  1504 	int n = merge_roots[node].front();
  1505 	Edge edge = node_data[n].first;
  1506 
  1507 	_kuratowski.set(edge, true);
  1508 	
  1509 	Node pred = node;
  1510 	node = _ugraph.target(edge);
  1511 	while (!pertinent(node, embed_edge, merge_roots)) {
  1512 	  edge = node_data[order_map[node]].first;
  1513 	  if (_ugraph.target(edge) == pred) {
  1514 	    edge = edge_lists[edge].next;
  1515 	  }
  1516 	  _kuratowski.set(edge, true);
  1517 	  pred = node;
  1518 	  node = _ugraph.target(edge);
  1519 	}
  1520       }
  1521       _kuratowski.set(embed_edge[node], true);
  1522     } 
  1523 
  1524     void markPredPath(Node node, Node snode, PredMap& pred_map) {
  1525       while (node != snode) {
  1526 	_kuratowski.set(pred_map[node], true);
  1527 	node = _ugraph.source(pred_map[node]);
  1528       }
  1529     }
  1530 
  1531     void markFacePath(Node ynode, Node xnode, 
  1532 		      OrderMap& order_map, NodeData& node_data) {
  1533       Edge edge = node_data[order_map[ynode]].first;
  1534       Node node = _ugraph.target(edge);
  1535       _kuratowski.set(edge, true);
  1536 	
  1537       while (node != xnode) {
  1538 	edge = node_data[order_map[node]].first;
  1539 	_kuratowski.set(edge, true);
  1540 	node = _ugraph.target(edge);
  1541       }
  1542     }
  1543 
  1544     void markInternalPath(std::vector<Edge>& path) {
  1545       for (int i = 0; i < int(path.size()); ++i) {
  1546 	_kuratowski.set(path[i], true);
  1547       }
  1548     }
  1549 
  1550     void markPilePath(std::vector<Edge>& path) {
  1551       for (int i = 0; i < int(path.size()); ++i) {
  1552 	_kuratowski.set(path[i], true);
  1553       }
  1554     }
  1555 
  1556     void isolateKuratowski(Edge edge, NodeData& node_data, 
  1557 			   EdgeLists& edge_lists, FlipMap& flip_map,
  1558 			   OrderMap& order_map, OrderList& order_list, 
  1559 			   PredMap& pred_map, ChildLists& child_lists,
  1560 			   AncestorMap& ancestor_map, LowMap& low_map, 
  1561 			   EmbedEdge& embed_edge, MergeRoots& merge_roots) {
  1562 
  1563       Node root = _ugraph.source(edge);
  1564       Node enode = _ugraph.target(edge);
  1565 
  1566       int rorder = order_map[root];
  1567 
  1568       TypeMap type_map(_ugraph, 0);
  1569 
  1570       int rn = findComponentRoot(root, enode, child_lists, 
  1571 				 order_map, order_list);
  1572 
  1573       Node xnode = order_list[node_data[rn].next];
  1574       Node ynode = order_list[node_data[rn].prev];
  1575 
  1576       // Minor-A
  1577       {
  1578 	while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
  1579 	  
  1580 	  if (!merge_roots[xnode].empty()) {
  1581 	    root = xnode;
  1582 	    rn = merge_roots[xnode].front();
  1583 	  } else {
  1584 	    root = ynode;
  1585 	    rn = merge_roots[ynode].front();
  1586 	  }
  1587 	  
  1588 	  xnode = order_list[node_data[rn].next];
  1589 	  ynode = order_list[node_data[rn].prev];
  1590 	}
  1591 	
  1592 	if (root != _ugraph.source(edge)) {
  1593 	  orientComponent(root, rn, order_map, pred_map, 
  1594 			  node_data, edge_lists, flip_map, type_map);
  1595 	  markFacePath(root, root, order_map, node_data);
  1596 	  int xlp = markExternalPath(xnode, order_map, child_lists, 
  1597 				     pred_map, ancestor_map, low_map);
  1598 	  int ylp = markExternalPath(ynode, order_map, child_lists, 
  1599 				     pred_map, ancestor_map, low_map);
  1600 	  markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
  1601 	  Node lwnode = findPertinent(ynode, order_map, node_data,
  1602 				     embed_edge, merge_roots);
  1603 	  
  1604 	  markPertinentPath(lwnode, order_map, node_data, edge_lists,
  1605 			    embed_edge, merge_roots);
  1606 	  
  1607 	  return;
  1608 	}
  1609       }
  1610       
  1611       orientComponent(root, rn, order_map, pred_map, 
  1612 		      node_data, edge_lists, flip_map, type_map);
  1613 
  1614       Node wnode = findPertinent(ynode, order_map, node_data,
  1615 				 embed_edge, merge_roots);
  1616       setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
  1617 
  1618       
  1619       //Minor-B
  1620       if (!merge_roots[wnode].empty()) {
  1621 	int cn = merge_roots[wnode].back();
  1622 	Node rep = order_list[cn - order_list.size()];
  1623 	if (low_map[rep] < rorder) {
  1624 	  markFacePath(root, root, order_map, node_data);
  1625 	  int xlp = markExternalPath(xnode, order_map, child_lists, 
  1626 				     pred_map, ancestor_map, low_map);
  1627 	  int ylp = markExternalPath(ynode, order_map, child_lists, 
  1628 				     pred_map, ancestor_map, low_map);
  1629 
  1630 	  Node lwnode, lznode;
  1631 	  markCommonPath(wnode, rorder, lwnode, lznode, order_list, 
  1632 			 order_map, node_data, edge_lists, embed_edge, 
  1633 			 merge_roots, child_lists, ancestor_map, low_map);
  1634 	  	  
  1635 	  markPertinentPath(lwnode, order_map, node_data, edge_lists,
  1636 			    embed_edge, merge_roots);
  1637 	  int zlp = markExternalPath(lznode, order_map, child_lists, 
  1638 				     pred_map, ancestor_map, low_map);
  1639 
  1640 	  int minlp = xlp < ylp ? xlp : ylp;
  1641 	  if (zlp < minlp) minlp = zlp;
  1642 
  1643 	  int maxlp = xlp > ylp ? xlp : ylp;
  1644 	  if (zlp > maxlp) maxlp = zlp;
  1645 	  
  1646 	  markPredPath(order_list[maxlp], order_list[minlp], pred_map);
  1647 	  
  1648 	  return;
  1649 	}
  1650       }
  1651 
  1652       Node pxnode, pynode;
  1653       std::vector<Edge> ipath;
  1654       findInternalPath(ipath, wnode, root, type_map, order_map,
  1655 		       node_data, edge_lists);
  1656       setInternalFlags(ipath, type_map);
  1657       pynode = _ugraph.source(ipath.front());
  1658       pxnode = _ugraph.target(ipath.back());
  1659 
  1660       wnode = findPertinent(pynode, order_map, node_data,
  1661 			    embed_edge, merge_roots);
  1662       
  1663       // Minor-C
  1664       {
  1665 	if (type_map[_ugraph.source(ipath.front())] == HIGHY) {
  1666 	  if (type_map[_ugraph.target(ipath.back())] == HIGHX) {
  1667 	    markFacePath(xnode, pxnode, order_map, node_data);
  1668 	  }
  1669 	  markFacePath(root, xnode, order_map, node_data);
  1670 	  markPertinentPath(wnode, order_map, node_data, edge_lists,
  1671 			    embed_edge, merge_roots);
  1672 	  markInternalPath(ipath);
  1673 	  int xlp = markExternalPath(xnode, order_map, child_lists, 
  1674 				     pred_map, ancestor_map, low_map);
  1675 	  int ylp = markExternalPath(ynode, order_map, child_lists, 
  1676 				     pred_map, ancestor_map, low_map);
  1677 	  markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
  1678 	  return;
  1679 	}
  1680 
  1681 	if (type_map[_ugraph.target(ipath.back())] == HIGHX) {
  1682 	  markFacePath(ynode, root, order_map, node_data);
  1683 	  markPertinentPath(wnode, order_map, node_data, edge_lists,
  1684 			    embed_edge, merge_roots);
  1685 	  markInternalPath(ipath);
  1686 	  int xlp = markExternalPath(xnode, order_map, child_lists, 
  1687 				     pred_map, ancestor_map, low_map);
  1688 	  int ylp = markExternalPath(ynode, order_map, child_lists, 
  1689 				     pred_map, ancestor_map, low_map);
  1690 	  markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
  1691 	  return;
  1692 	}
  1693       }
  1694 
  1695       std::vector<Edge> ppath;
  1696       findPilePath(ppath, root, type_map, order_map, node_data, edge_lists);
  1697       
  1698       // Minor-D
  1699       if (!ppath.empty()) {
  1700 	markFacePath(ynode, xnode, order_map, node_data);
  1701 	markPertinentPath(wnode, order_map, node_data, edge_lists,
  1702 			  embed_edge, merge_roots);
  1703 	markPilePath(ppath);
  1704 	markInternalPath(ipath);
  1705 	int xlp = markExternalPath(xnode, order_map, child_lists, 
  1706 				   pred_map, ancestor_map, low_map);
  1707 	int ylp = markExternalPath(ynode, order_map, child_lists, 
  1708 				   pred_map, ancestor_map, low_map);
  1709 	markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
  1710 	return;
  1711       }
  1712 
  1713       // Minor-E*
  1714       {
  1715 
  1716 	if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
  1717 	  Node znode = findExternal(pynode, rorder, order_map, 
  1718 				    child_lists, ancestor_map,
  1719 				    low_map, node_data);
  1720 	  
  1721 	  if (type_map[znode] == LOWY) {
  1722 	    markFacePath(root, xnode, order_map, node_data);
  1723 	    markPertinentPath(wnode, order_map, node_data, edge_lists,
  1724 			      embed_edge, merge_roots);
  1725 	    markInternalPath(ipath);
  1726 	    int xlp = markExternalPath(xnode, order_map, child_lists, 
  1727 				       pred_map, ancestor_map, low_map);
  1728 	    int zlp = markExternalPath(znode, order_map, child_lists, 
  1729 				       pred_map, ancestor_map, low_map);
  1730 	    markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
  1731 	  } else {
  1732 	    markFacePath(ynode, root, order_map, node_data);
  1733 	    markPertinentPath(wnode, order_map, node_data, edge_lists,
  1734 			      embed_edge, merge_roots);
  1735 	    markInternalPath(ipath);
  1736 	    int ylp = markExternalPath(ynode, order_map, child_lists, 
  1737 				       pred_map, ancestor_map, low_map);
  1738 	    int zlp = markExternalPath(znode, order_map, child_lists, 
  1739 				       pred_map, ancestor_map, low_map);
  1740 	    markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
  1741 	  }
  1742 	  return;
  1743 	}
  1744 
  1745 	int xlp = markExternalPath(xnode, order_map, child_lists, 
  1746 				   pred_map, ancestor_map, low_map);
  1747 	int ylp = markExternalPath(ynode, order_map, child_lists, 
  1748 				   pred_map, ancestor_map, low_map);
  1749 	int wlp = markExternalPath(wnode, order_map, child_lists, 
  1750 				   pred_map, ancestor_map, low_map);
  1751 
  1752 	if (wlp > xlp && wlp > ylp) {
  1753 	  markFacePath(root, root, order_map, node_data);
  1754 	  markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
  1755 	  return;
  1756 	}
  1757 
  1758 	markInternalPath(ipath);
  1759 	markPertinentPath(wnode, order_map, node_data, edge_lists,
  1760 			  embed_edge, merge_roots);
  1761 
  1762 	if (xlp > ylp && xlp > wlp) {
  1763 	  markFacePath(root, pynode, order_map, node_data);
  1764 	  markFacePath(wnode, xnode, order_map, node_data);
  1765 	  markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
  1766 	  return;
  1767 	}
  1768 
  1769 	if (ylp > xlp && ylp > wlp) {
  1770 	  markFacePath(pxnode, root, order_map, node_data);
  1771 	  markFacePath(ynode, wnode, order_map, node_data);
  1772 	  markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
  1773 	  return;
  1774 	}
  1775 
  1776 	if (pynode != ynode) {
  1777 	  markFacePath(pxnode, wnode, order_map, node_data);
  1778 
  1779 	  int minlp = xlp < ylp ? xlp : ylp;
  1780 	  if (wlp < minlp) minlp = wlp;
  1781 
  1782 	  int maxlp = xlp > ylp ? xlp : ylp;
  1783 	  if (wlp > maxlp) maxlp = wlp;
  1784 	  
  1785 	  markPredPath(order_list[maxlp], order_list[minlp], pred_map);
  1786 	  return;
  1787 	}
  1788 
  1789 	if (pxnode != xnode) {
  1790 	  markFacePath(wnode, pynode, order_map, node_data);
  1791 
  1792 	  int minlp = xlp < ylp ? xlp : ylp;
  1793 	  if (wlp < minlp) minlp = wlp;
  1794 
  1795 	  int maxlp = xlp > ylp ? xlp : ylp;
  1796 	  if (wlp > maxlp) maxlp = wlp;
  1797 	  
  1798 	  markPredPath(order_list[maxlp], order_list[minlp], pred_map);
  1799 	  return;
  1800 	}
  1801 
  1802 	markFacePath(root, root, order_map, node_data);
  1803 	int minlp = xlp < ylp ? xlp : ylp;
  1804 	if (wlp < minlp) minlp = wlp;
  1805 	markPredPath(root, order_list[minlp], pred_map);
  1806 	return;
  1807       }
  1808       
  1809     }
  1810 
  1811   };
  1812 
  1813 }
  1814 
  1815 #endif