Check whether a given graph is Bipartite or not
Last Updated :
23 Jul, 2025
Given a graph with V vertices numbered from 0 to V-1 and a list of edges, determine whether the graph is bipartite or not.
Note: A bipartite graph is a type of graph where the set of vertices can be divided into two disjoint sets, say U and V, such that every edge connects a vertex in U to a vertex in V, there are no edges between vertices within the same set.
Example:
Input: V = 4, edges[][]= [[0, 1], [0, 2], [1, 2], [2, 3]]
Output: false
Explanation:
node 1 and node 2 have same color while coloringThe graph is not bipartite because no matter how we try to color the nodes using two colors, there exists a cycle of odd length (like 1–2–0–1), which leads to a situation where two adjacent nodes end up with the same color. This violates the bipartite condition, which requires that no two connected nodes share the same color.
Input: V = 4, edges[][] = [[0, 1], [1, 2], [2, 3]]
Output: true
Explanation:
The given graph can be colored in two colors so, it is a bipartite graph.
Using Breadth-First Search (BFS)
Checking if a graph is bipartite is like trying to color the graph using only two colors, so that no two adjacent vertices have the same color. One approach is to check whether the graph is 2-colorable or not using backtracking algorithm m coloring problem.
A common and efficient way to solve this is by using Breadth-First Search (BFS). The idea is to traverse the graph level by level and assign colors alternately to the vertices as we proceed.
Step-by-step approach:
- Start BFS from any uncolored vertex and assign it color 0.
- For each vertex, color its uncolored neighbors with the opposite color (1 if current is 0, and vice versa)
- Check if a neighbor already has the same color as the current vertex, return false (graph is not bipartite).
- If BFS completes without any conflicts, return true (graph is bipartite).
Below is the implementation of the above approach:
C++
//Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> constructadj(int V, vector<vector<int>> &edges){
vector<vector<int>> adj(V);
for(auto it:edges){
adj[it[0]].push_back(it[1]);
adj[it[1]].push_back(it[0]);
}
return adj;
}
// Function to check if the graph is Bipartite using BFS
//Driver Code Ends
bool isBipartite(int V, vector<vector<int>> &edges) {
// Vector to store colors of vertices.
// Initialize all as -1 (uncolored)
vector<int> color(V, -1);
//create adjacency list
vector<vector<int>> adj = constructadj(V,edges);
// Queue for BFS
queue<int> q;
// Iterate through all vertices to handle disconnected graphs
for(int i = 0; i < V; i++) {
// If the vertex is uncolored, start BFS from it
if(color[i] == -1) {
// Assign first color (0) to the starting vertex
color[i] = 0;
q.push(i);
// Perform BFS
while(!q.empty()) {
int u = q.front();
q.pop();
// Traverse all adjacent vertices
for(auto &v : adj[u]) {
// If the adjacent vertex is uncolored,
// assign alternate color
if(color[v] == -1) {
color[v] = 1 - color[u];
q.push(v);
}
// If the adjacent vertex has the same color,
// graph is not bipartite
else if(color[v] == color[u]) {
return false;
}
}
}
}
}
// If no conflicts in coloring, graph is bipartite
//Driver Code Starts
return true;
}
int main() {
int V = 4;
vector<vector<int>> edges = {{0, 1}, {0, 2}, {1, 2}, {2, 3}};
if(isBipartite(V, edges))
cout << "true";
else
cout << "false";
return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util.*;
class GfG {
// Function to construct the adjacency list from edges
static ArrayList<ArrayList<Integer>> constructadj(int V, int[][] edges) {
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
for (int i = 0; i < V; i++) {
adj.add(new ArrayList<>());
}
for (int[] edge : edges) {
int u = edge[0];
int v = edge[1];
adj.get(u).add(v);
adj.get(v).add(u);
}
return adj;
}
// Function to check if the graph is Bipartite using BFS
//Driver Code Ends
static boolean isBipartite(int V,int[][] edges) {
int[] color = new int[V];
Arrays.fill(color, -1);
// create adjacency list
ArrayList<ArrayList<Integer>> adj = constructadj(V,edges);
for (int i = 0; i < V; i++) {
if (color[i] == -1) {
Queue<Integer> q = new LinkedList<>();
color[i] = 0;
q.offer(i);
while (!q.isEmpty()) {
int u = q.poll();
for (int v : adj.get(u)) {
if (color[v] == -1) {
color[v] = 1 - color[u];
q.offer(v);
} else if (color[v] == color[u]) {
return false; // Conflict found
}
}
}
}
//Driver Code Starts
}
return true;
}
public static void main(String[] args) {
int V = 4;
// Edges of the graph
int[][] edges = {{0, 1}, {0, 2}, {1, 2}, {2, 3}};
// Check if the graph is bipartite
System.out.println(isBipartite(V, edges));
}
}
//Driver Code Ends
Python
#Driver Code Starts
from collections import deque
# Function to construct the adjacency list from edges
def constructadj(V, edges):
adj = [[] for _ in range(V)]
for edge in edges:
u, v = edge
adj[u].append(v)
adj[v].append(u)
return adj
# Function to check if the graph is Bipartite using BFS
#Driver Code Ends
def isBipartite(V, adj):
# Initialize all as uncolored
color = [-1] * V
# create adjacency list
adj = constructadj(V,edges)
for i in range(V):
if color[i] == -1:
color[i] = 0
q = deque([i])
while q:
u = q.popleft()
for v in adj[u]:
if color[v] == -1:
color[v] = 1 - color[u]
q.append(v)
elif color[v] == color[u]:
return False # Conflict found
#Driver Code Starts
# No conflict, graph is bipartite
return True
if __name__ == "__main__":
V = 4
edges = [[0, 1], [0, 2], [1, 2], [2, 3]]
print("true" if isBipartite(V, edges) else "false")
#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;
class GfG {
public static List<List<int>> constructadj(int V, List<List<int>> edges)
{
List<List<int>> adj = new List<List<int>>();
for (int i = 0; i < V; i++)
adj.Add(new List<int>());
foreach (var edge in edges)
{
int u = edge[0];
int v = edge[1];
adj[u].Add(v);
adj[v].Add(u);
}
return adj;
}
//Driver Code Ends
// Function to check if the graph is Bipartite using BFS
public static bool IsBipartite(int V,
List<List<int> > edges){
int[] color = new int[V];
// create adjacency list
List<List<int>> adj = constructadj(V, edges);
// Initialize all as -1 (uncolored)
Array.Fill(color, -1);
// Iterate through all vertices to handle
// disconnected graphs
for (int i = 0; i < V; i++) {
// If the vertex is uncolored, start BFS from it
if (color[i] == -1) {
// Assign first color (0)
color[i] = 0;
Queue<int> q = new Queue<int>();
q.Enqueue(i);
// Perform BFS
while (q.Count > 0) {
int u = q.Dequeue();
// Traverse all adjacent vertices
foreach(int v in adj[u]){
// If the adjacent vertex is
// uncolored, assign alternate color
if (color[v] == -1) {
color[v] = 1 - color[u];
q.Enqueue(v);
}
// If the adjacent vertex has the
// same color, graph is not
// bipartite
else if (color[v] == color[u]) {
return false;
}
}
}
}
}
// If no conflicts in coloring, graph is bipartite
//Driver Code Starts
return true;
}
static void Main(){
int V = 4;
List<List<int>> edges = new List<List<int>> {
new List<int>{0, 1},
new List<int>{0, 2},
new List<int>{1, 2},
new List<int>{2, 3}
};
if (IsBipartite(V, edges))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
//Driver Code Ends
JavaScript
//Driver Code Starts
// Function to construct adjacency list from edges
function constructadj(V, edges) {
const adj = Array.from({ length: V }, () => []);
for (const [u, v] of edges) {
adj[u].push(v);
adj[v].push(u); // undirected graph
}
return adj;
}
//Driver Code Ends
function isBipartite(V, edges){
// Initialize all as -1 (uncolored)
const color = Array(V).fill(-1);
// create adjacency list
let adj = constructadj(V,edges);
// Iterate through all vertices to handle disconnected
// graphs
for (let i = 0; i < V; i++) {
// If the vertex is uncolored, start BFS from it
if (color[i] === -1) {
// Assign first color (0)
color[i] = 0;
const queue = [ i ];
// Perform BFS
while (queue.length > 0) {
const u = queue.shift();
// Traverse all adjacent vertices
for (let v of adj[u]) {
// If the adjacent vertex is uncolored,
// assign alternate color
if (color[v] === -1) {
color[v] = 1 - color[u];
queue.push(v); // Push to queue
}
// If the adjacent vertex has the same
// color, graph is not bipartite
else if (color[v] === color[u]) {
return false;
}
}
}
}
}
// If no conflicts in coloring, graph is bipartite
//Driver Code Starts
return true;
}
// Driver Code
const V = 4;
const adj = Array.from({length : V}, () => []);
let edges = [[0, 1], [0, 2], [1, 2], [2, 3]];
console.log(isBipartite(V, edges));
//Driver Code Ends
Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges. This is because BFS explores each vertex and edge exactly once.
Auxiliary Space: O(V), The queue used in BFS, which can hold up to V vertices and The color array (or map), which stores the color for each vertex, We do not count the adjacency list in auxiliary space as it is necessary for representing the input graph.
Using Depth-First Search (DFS)
We can also check if a graph is bipartite using Depth-First Search (DFS). We need to color the graph with two colors such that no two adjacent vertices share the same color. We start from any uncolored vertex, assigning it a color (e.g., color 0). As we explore each vertex, we recursively color its uncolored neighbors with the another color. If we ever find a neighbor that shares the same color as the current vertex, we can simply conclude that the graph is not bipartite. If there is no conflict found after the traversal then the given graph is bipartite.
For implementation of DFS approach please refer to this article "Check if a given graph is Bipartite using DFS".
Related Article:
Algorithm and Code for Bipartite Graph
Similar Reads
Basics & Prerequisites
Data Structures
Getting Started with Array Data StructureArray is a collection of items of the same variable type that are stored at contiguous memory locations. It is one of the most popular and simple data structures used in programming. Basic terminologies of ArrayArray Index: In an array, elements are identified by their indexes. Array index starts fr
14 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem