private static void RecursiveSeparation(PlanarGraph pg,
                                                PlanarNode src,
                                                List <PlanarNode> orderNodes, SeparatorCycle sepCycle)
        {
            PlanarEdge sepE;

            Bfs.Src_all_bfs(src, pg.planarNodes, pg.planarEdges, true);


            if (pg.planarNodes.Count < nodesCount / 10 ||
                !FindSeparator(src, orderNodes, pg, sepCycle, out sepE))
            {
                Console.WriteLine("Leaf:" + gc + "  " + pg.planarNodes.Count);
                return;
            }

            List <PlanarNode> cycleNodes
                = sepCycle.cycle
                  .Where(x => pg.planarNodes.Keys.Contains(x))
                  .Select(x => pg.planarNodes[x]).ToList();

            gc++;
            PlanarGraph g0 = new PlanarGraph(sepCycle.inC, cycleNodes, src,
                                             new Dictionary <int, PlanarEdge>(pg.planarEdges));

            PlanarGraph g1 = new PlanarGraph(sepCycle.outC, cycleNodes, src,
                                             new Dictionary <int, PlanarEdge>(pg.planarEdges));

            RecursiveSeparation(g0, g0.planarNodes[srcId], orderNodes, sepCycle);
            gc++;
            Bfs.Src_all_bfs(src, pg.planarNodes, pg.planarEdges, true);
            RecursiveSeparation(g1, g1.planarNodes[srcId], orderNodes, sepCycle);
        }
        private static bool FindSeparatorOnTriangulation(PlanarNode src,
                                                         PlanarGraph pg,
                                                         SeparatorCycle sepCycle)
        {
            pg = Triangulation.GetTriangulation(pg);
            foreach (PlanarEdge f in Triangulation.triEdges)
            {
                if (((PlanarNode)f.neighboursAdjEdges[0]).nid == srcId ||
                    ((PlanarNode)f.neighboursAdjEdges[1]).nid == srcId)
                {
                    continue;
                }
                PlanarNode src2 = pg.planarNodes[srcId];
                Bfs.Src_all_bfs(src2, pg.planarNodes, pg.planarEdges, true);

                sepCycle.GetBoundaryCycle(pg, src2, f);

                int max = (int)(c * pg.planarNodes.Count);
                if (sepCycle.inC.Count < max &&
                    sepCycle.outC.Count < max)
                {
                    Console.WriteLine(gc + "  " + sepCycle.inC.Count);
                    //  ResetGraph(pg);
                    return(true);
                }

                ResetGraph(pg);
                //          break;
            }



            Console.WriteLine("not: " + gc + "  " + pg.planarNodes.Count);
            return(false);
        }
        public List <PlanarNode> SeparateByEdge(
            PlanarEdge f, PlanarNode src,
            out List <PlanarNode> inC, out List <PlanarNode> outC)
        {
            Bfs.Src_all_bfs(src, g.planarNodes, g.planarEdges, true);
            SetCycleCost(f);
            Bfs.Src_all_bfs(src, g.planarNodes, g.planarEdges, true);
            inC  = new List <PlanarNode>();
            outC = new List <PlanarNode>();
            List <PlanarNode> sep = new List <PlanarNode>();

            foreach (PlanarNode n in g.planarNodes.Values)
            {
                if (cycle.Contains(n.nid))
                {
                    continue;
                }
                if (n.insideCycle)
                {
                    inC.Add(n);
                    n.insideCycle = false;
                }
                else
                {
                    outC.Add(n);
                }
            }
            return(sep);
        }
        private static bool FindSeparator(PlanarNode src,
                                          List <PlanarNode> orderNodes, PlanarGraph pg,
                                          SeparatorCycle sepCycle, out PlanarEdge f)
        {
            List <PlanarNode> insideBoundaryNodes =
                orderNodes
                .Where(y => pg.planarNodes.ContainsKey(y.nid)).ToList();

            for (int i = 0; i < insideBoundaryNodes.Count - 1; i = i + 1)
            {
                for (int j = i + 1; j < insideBoundaryNodes.Count; j = j + 1)
                {
                    PlanarNode src2 = pg.planarNodes[srcId];
                    Bfs.Src_all_bfs(src2, pg.planarNodes, pg.planarEdges, true);
                    PlanarNode u = pg.planarNodes[insideBoundaryNodes[i].nid];
                    PlanarNode v = pg.planarNodes[insideBoundaryNodes[j].nid];
                    f      = new PlanarEdge(u, v);
                    f.eid  = -pg.planarEdges.Count - 1;
                    f.trgl = true;
                    pg.planarEdges.Add(f.eid, f);
                    u.edgesIds.Add(f.eid);
                    v.edgesIds.Add(f.eid);
                    //   SeparatorCycle sepCycle = new SeparatorCycle();
                    sepCycle.GetBoundaryCycle(pg, src2, f);

                    int max = (int)(c * pg.planarNodes.Count);
                    if (sepCycle.inC.Count < max &&
                        sepCycle.outC.Count < max)
                    {
                        Console.WriteLine(gc + "  " + sepCycle.inC.Count + " " + u.nid + " " + v.nid);
                        //  ResetGraph(pg);
                        return(true);
                    }

                    else
                    {
                        u.edgesIds.Remove(f.eid);
                        v.edgesIds.Remove(f.eid);
                    }
                    ResetGraph(pg);
                    //          break;
                }
            }
            f = null;
            if (c == 4f / 5)
            {
                c = 19f / 20;
                return(FindSeparator(src, orderNodes, pg, sepCycle, out f));
            }
            else

            {
                //   c = 4f / 5;
                Console.WriteLine("not: " + gc + "  " + pg.planarNodes.Count);
                return(FindSeparatorOnTriangulation(src, pg, sepCycle));
            }
        }
        public bool GetBoundaryCycle(PlanarGraph graph, PlanarNode src,
                                     PlanarEdge f) //step 8
        {
            g = graph;

            allCostSum = g.planarNodes.Count; //cost=1
            int index = allCostSum / 2;

            SetCycleCost(f);
            src.insideCycle = false;
            Bfs.Src_all_bfs(src, g.planarNodes, g.planarEdges, true);
            inC  = new List <PlanarNode>();
            outC = new List <PlanarNode>();
            order++;
            foreach (PlanarNode n in g.planarNodes.Values)
            {
                if (cycle.Contains(n.nid))
                {
                    continue;
                }
                if (n.insideCycle)
                {
                    inC.Add(n);
                    n.insideCycle = false;
                }

                else// if (!cycle.Contains(n.nid))
                {
                    outC.Add(n);
                };                //vc sep
            }

            List <PlanarNode> min;

            if (inC.Count > outC.Count)
            {
                min = outC;
            }
            else
            {
                min = inC;
            }
            // if (!cyclesNodes.ContainsKey(f.eid))
            //      cyclesNodes.Add(f.eid, min);
            return(min.Count > (g.planarNodes.Count) / 3);
        }
        PlanarNode src; //, newSrc;
        //   public PlanarGraph shrGraph;  //shrinked
        //   Dictionary<long, PlanarNode> shrNodes = new Dictionary<long, PlanarNode>();

        /*  public Dictionary<int, List<long>> Separate(PlanarGraph pg, out List<long> cycle)
         * {
         *    return Separate(pg.planarNodes, pg.planarEdges, out cycle);
         * }
         */



        public Dictionary <int, List <long> > Separate(
            ref PlanarGraph pg, out List <long> cycle)
        {
            planarNodes = pg.planarNodes;
            planarEdges = pg.planarEdges;
            src         = planarNodes.First().Value;
            Bfs.Src_all_bfs(src, pg.planarNodes, planarEdges);

            // step 3, 4, 5
            Dictionary <int, List <long> > levels = CreateMainLevels(src.nid);

            //step 6
            //    PlanarGraph shrinkedGraph = pg;// CreateShrinkedGraph(levels, pg,src.nid);
            //       foreach (long nid in levels[int.MaxValue])
            //           shrinkedGraph.planarNodes.Remove(nid);
            //step 7
            //     Bfs.Src_all_bfs(src, shrinkedGraph.planarEdges);
            SeparatorUtils.SetAllSumsOfDescNodesIncludeItself(pg, src, 1);
            if (Triangulation.triEdges == null || Triangulation.triEdges.Count == 0)
            {
                pg = Triangulation.GetTriangulation(pg);
            }
            //       PlanarEdge xx = shrinkedGraph.planarEdges[1630674];
            //step 8
            //     SeparatorCycle sepCycle = new SeparatorCycle();
            //      StreamWriter w = new StreamWriter("C:\\Users\\L\\Desktop\\triCycles2.txt");
            try
            {
                //          sepCycle.GetFirstCycle(shrinkedGraph, src, lev0);
            }
            catch { };
            //     foreach (string s in sepCycle.outputs)
            //         w.WriteLine(s);
            //     w.Close();
            cycle = null;
            return(new Dictionary <int, List <long> >());

            /*
             *
             * PlanarGraph trg = Triangulation.GetTriangulation(
             *  new PlanarGraph(plNodes, plEdges));
             * foreach (int eid in planarEdges.Keys.Reverse<int>())
             * {
             *  break;
             *  PlanarEdge e = trg.planarEdges[eid];
             *  if (e.inTree)
             *      continue;
             *  PlanarNode u = (PlanarNode)e.neighboursAdjEdges[0];
             *  PlanarNode v = (PlanarNode)e.neighboursAdjEdges[1];
             *  List<long> pathU = new List<long>();
             *  List<long> pathV = new List<long>();
             *  PlanarNode x = u;
             *
             *  while (x.parent != null)
             *  {
             *      x.state = -3;
             *      pathU.Add(x.nid);
             *      x = x.parent;
             *  }
             *  pathV = new List<long>();
             *  x = v;
             *
             *  while (x.parent != null && x.parent.state != -3)
             *  {
             *      pathV.Add(x.nid);
             *      x = x.parent;
             *  }
             *  pathV.Add(x.nid);
             * }
             *
             * /////////////////////////
             *
             * planarNodes = trg.planarNodes;
             * planarEdges = trg.planarEdges;
             *
             * GoAroundBnfTree(levels);
             *
             * SeparatorUtils.UpdateNextEdges(newSrc, plEdges);
             * SeparatorUtils.UpdateNextEdges(src, planarEdges);
             * shrNodes.Add(newSrc.nid, newSrc);
             * //shrGraph = new PlanarGraph(shrNodes, planarEdges);
             *
             * SeparatorUtils.RemoveEdges(shrGraph, newSrc, lev0, lev2);
             * SeparatorUtils.SetAllSumsOfDescNodesIncludeItself(shrGraph, 1);
             *
             * SeparatorCycle sepCycle = new SeparatorCycle();
             * sepCycle.GetFirstCycle(trg);
             *
             *
             *
             * src = newSrc;
             * cycle = sepCycle.cycle;
             * return levels;
             */
        }
        public void GetFirstCycle(PlanarGraph graph, PlanarNode src,
                                  int lev0) //step 8
        {
            g = graph;

            allCostSum = g.planarNodes.Count; //cost=1
            int index = allCostSum / 2;       //od pol.
                                              //   bool found = false;
                                              //    PlanarEdge e = null;
                                              //      for (int i = index; i < g.planarNodes.Count; i++)
                                              //      {
                                              //          foreach (int eid in g.planarNodes.ElementAt(i).Value.edgesIds)
            PlanarEdge f;

            if (order <= 1)
            {
                f = g.planarEdges[1630674];
            }
            else
            {
                if (orderedTriE == null)
                {
                    Init(lev0);
                }
                if (orderedTriE.Count == 0)
                {
                    return;
                }
                f = orderedTriE[0];
                orderedTriE.RemoveAt(0);
            }



            SetCycleCost(f);
            src.insideCycle = false;
            Bfs.Src_all_bfs(src, g.planarNodes, g.planarEdges, true);
            inC  = new List <PlanarNode>();
            outC = new List <PlanarNode>();
            order++;
            foreach (PlanarNode n in g.planarNodes.Values)
            {
                if (cycle.Contains(n.nid))
                {
                    continue;
                }
                if (n.insideCycle)
                {
                    inC.Add(n);
                    n.insideCycle = false;
                }

                else// if (!cycle.Contains(n.nid))
                {
                    outC.Add(n);
                };                //vc sep
            }

            List <PlanarNode> min;

            if (inC.Count > outC.Count)
            {
                min = outC;
            }
            else
            {
                min = inC;
            }
            // if (!cyclesNodes.ContainsKey(f.eid))
            //      cyclesNodes.Add(f.eid, min);
            if (min.Count < g.planarNodes.Count / 13)
            {
                GetFirstCycle(g, src, lev0);
            }
        }