Пример #1
0
        /// <summary>
        /// Return true if the graph is (complete) bipartite
        /// Time complexity: O(V + E)
        /// </summary>
        /// <param name="graph">graph</param>
        /// <returns>(bool, bool) - the first item stands for bipartite and the second item stands for complete
        /// (true, true) - complete bipartite graph
        /// (true, false) - bipartite graph
        /// (false, - ) - the graph is not (complete) bipartite</returns>
        public static Tuple <bool, bool> IsBipartiteGraph(IGraphInterface graph)
        {
            // Variable
            IVertexInterface        vertex;
            List <IVertexInterface> neighboursVertexList;
            bool isFirstPartite, isBipartite = true;

            HashSet <IVertexInterface> firstPartite  = new HashSet <IVertexInterface>();
            HashSet <IVertexInterface> secondPartite = new HashSet <IVertexInterface>();
            Queue <IVertexInterface>   vertexQueue   = new Queue <IVertexInterface>();

            vertex = graph.GetFirstVertex();
            vertexQueue.Enqueue(vertex);
            firstPartite.Add(vertex);

            while (vertexQueue.Count != 0)
            {
                vertex = vertexQueue.Dequeue();
                neighboursVertexList = graph.Neighbours(vertex);

                if (firstPartite.Contains(vertex))
                {
                    isFirstPartite = true;
                }
                else
                {
                    isFirstPartite = false;
                }

                foreach (IVertexInterface neighbourVertex in neighboursVertexList)
                {
                    if (!firstPartite.Contains(neighbourVertex) && !secondPartite.Contains(neighbourVertex))
                    {
                        if (isFirstPartite)
                        {
                            secondPartite.Add(neighbourVertex);
                        }
                        else
                        {
                            firstPartite.Add(neighbourVertex);
                        }

                        vertexQueue.Enqueue(neighbourVertex);
                    }
                    else
                    {
                        if ((firstPartite.Contains(neighbourVertex) && isFirstPartite) || (secondPartite.Contains(neighbourVertex) && !isFirstPartite))
                        {
                            isBipartite = false;
                        }
                    }
                }
            }

            if (!isBipartite)
            {
                return(new Tuple <bool, bool>(false, false));
            }

            // Set bipartites
            graph.GetGraphProperty().SetPartites(firstPartite.ToList(), secondPartite.ToList());

            // Variable
            int countFirstPartiteVertex  = firstPartite.Count;
            int countSecondPartiteVertex = secondPartite.Count;

            // Is the graph a complete bipartite graph
            foreach (Vertex firstPartiteVertex in firstPartite)
            {
                if (graph.CountNeighbours(firstPartiteVertex) != countSecondPartiteVertex)
                {
                    return(new Tuple <bool, bool>(true, false));
                }
            }
            foreach (Vertex secondPartiteVertex in secondPartite)
            {
                if (graph.CountNeighbours(secondPartiteVertex) != countFirstPartiteVertex)
                {
                    return(new Tuple <bool, bool>(true, false));
                }
            }

            return(new Tuple <bool, bool>(true, true));
        }