public GraphColor[] Find3Colorings(UndirectedGraph <int, IEdge <int> > graph)
        {
            //Initialize structures
            _graph           = graph.Clone();
            _availableColors = new HashSet <GraphColor> [_graph.VertexCount];
            for (int i = 0; i < _graph.VertexCount; i++)
            {
                _availableColors[i] = new HashSet <GraphColor>()
                {
                    GraphColor.Black, GraphColor.Gray, GraphColor.White
                }
            }
            ;
            _coloring = new GraphColor?[_graph.VertexCount];

            //Get all components of G
            List <UndirectedGraph <int, IEdge <int> > > G_components = FindComponents(_graph);

            foreach (UndirectedGraph <int, IEdge <int> > component in G_components)
            {
                //Find separator S for component
                HashSet <int> S = PlanarSeparator.FindSeparator(component);
                ////Split component into smaller components
                foreach (int v in S)
                {
                    component.RemoveVertex(v);
                }
                List <UndirectedGraph <int, IEdge <int> > > components = FindComponents(component);

                //One of components cannot be colored => whole G cannot be colored
                //Slow version
                if (!DnCColoring(components, S))
                {
                    return(null);
                }
                //Fast version
                //if (!BruteForceColoring(new List<UndirectedGraph<int, IEdge<int>>>(), _graph.Vertices.ToHashSet()))
                //    return null;
            }
            return(_coloring.Select(c => c.Value).ToArray());
        }
        public GraphColor[] Find3Colorings(UndirectedGraph <int, IEdge <int> > graph)
        {
            //Initialize structures
            _graph           = graph.Clone();
            _availableColors = new HashSet <GraphColor> [_graph.VertexCount];
            for (int i = 0; i < _graph.VertexCount; i++)
            {
                _availableColors[i] = new HashSet <GraphColor>()
                {
                    GraphColor.Black, GraphColor.Gray, GraphColor.White
                }
            }
            ;
            _coloring = new GraphColor?[_graph.VertexCount];

            //Get all components of G
            (List <UndirectedGraph <int, IEdge <int> > > list, Dictionary <int, int> dict)G_components = FindComponents(_graph);
            foreach (UndirectedGraph <int, IEdge <int> > component in G_components.list)
            {
                //Find separator S for component
                HashSet <int> S = PlanarSeparator.FindSeparator(component);
                ////Split component into smaller components
                foreach (int v in S)
                {
                    component.RemoveVertex(v);
                }
                (List <UndirectedGraph <int, IEdge <int> > >, Dictionary <int, int>)components = FindComponents(component);

                //One of components cannot be colored => whole G cannot be colored
                if (!DnCColoring(components, S).isColorable)
                {
                    return(null);
                }
            }
            return(_coloring.Select(c => c.Value).ToArray());
        }
        private bool DnCColoring(List <UndirectedGraph <int, IEdge <int> > > components, HashSet <int> s)
        {
            //Separator colored
            if (s.Count == 0)
            {
                foreach (UndirectedGraph <int, IEdge <int> > component in components)
                {
                    if (component.VertexCount < 15)
                    {
                        //Can't find separator for component - color using bruteforce
                        if (!DnCColoring(new List <UndirectedGraph <int, IEdge <int> > >(),
                                         new HashSet <int>(component.Vertices)))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        HashSet <int> sPrim = PlanarSeparator.FindSeparator(component);
                        UndirectedGraph <int, IEdge <int> > componentCopy = component.Clone();
                        foreach (int vPrim in sPrim)
                        {
                            componentCopy.RemoveVertex(vPrim);
                        }
                        List <UndirectedGraph <int, IEdge <int> > > componentsPrim = FindComponents(componentCopy);
                        if (!DnCColoring(componentsPrim, sPrim))
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            }

            //Separator still not colored
            int v = s.First();

            s.Remove(v);
            foreach (GraphColor color in (GraphColor[])Enum.GetValues(typeof(GraphColor)))
            {
                if (!_availableColors[v].Contains(color))
                {
                    continue;
                }

                //Color v with color
                _coloring[v] = color;
                bool       moveToNextColor        = false;
                List <int> verticesWithTakenColor = new List <int>();

                foreach (int n in _graph.AdjacentVertices(v))
                {
                    if (_availableColors[n].Contains(color))
                    {
                        //Adjacent not colored vertex has no available color - invalid coloring
                        if (_availableColors[n].Count == 1)
                        {
                            //Reverse changes
                            foreach (int vertex in verticesWithTakenColor)
                            {
                                _availableColors[vertex].Add(color);
                            }
                            //Move to next v coloring
                            moveToNextColor = true;
                            break;
                        }

                        //Adjacent vertices cannot be colored with color
                        _availableColors[n].Remove(color);
                        verticesWithTakenColor.Add(n);
                    }
                }

                if (moveToNextColor)
                {
                    continue;
                }

                if (DnCColoring(components, s))
                {
                    return(true);
                }

                //Reverse changes
                foreach (int vertex in verticesWithTakenColor)
                {
                    _availableColors[vertex].Add(color);
                }
            }
            s.Add(v);
            return(false);
        }