/// <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)); }