Junior 6 min · March 05, 2026

Bipartite Graph Check — Disconnected Component Trap

Single-source BFS misses odd cycles in disconnected components.

N
Naren Founder & Principal Engineer

20+ years shipping performance-critical code where algorithms decide the bill. Drawn from code that ran under real load.

Follow
Production
production tested
May 23, 2026
last updated
1,554
articles · all by Naren
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Bipartite graph: nodes can be split into two sets so every edge connects across sets
  • 2-coloring with BFS: assign alternating colors to neighbors; conflict means odd cycle
  • Disconnected graphs: run BFS from each uncolored component
  • Real-world use: job matching, scheduling, and detecting conflicts in recommendation systems
  • Odd cycle existence is the sole reason a graph fails bipartiteness
  • BFS runs in O(V+E) time, O(V) space; DFS works identically with similar complexity
✦ Definition~90s read
What is Bipartite Graph Check?

A graph is bipartite if you can color every node with one of two colors such that no two adjacent nodes share the same color. Imagine trying to seat guests at a party where certain pairs don't get along — you put one group on the left side and another on the right, ensuring every conflict is between sides, not within.

Imagine you're organizing a school dance.

Common examples: job assignment graphs (workers on one side, jobs on the other), class scheduling (students on one side, courses on the other), and movie recommendation systems (users and movies as two distinct sets). A graph is bipartite if and only if it contains no odd-length cycle.

BFS or DFS can check this in O(V+E) by attempting to 2-color the graph and failing when a conflict is found.

Plain-English First

Imagine you're organizing a school dance. You want every boy paired with a girl — no boy-boy or girl-girl pairs on the dance floor. A bipartite graph is just that: a group of people (or things) that can be split into two teams so that everyone on Team A only connects to someone on Team B, never to their own teammates. If you can pull off that split, the graph is bipartite. If two teammates are directly connected, it's not.

Graphs show up everywhere in software — social networks, recommendation engines, scheduling systems, even compilers. But not all graphs are created equal. Some have a hidden structure that unlocks powerful optimizations, and bipartiteness is one of the most practically useful of those structures. Knowing whether a graph is bipartite is the difference between a Netflix that recommends movies you'll actually watch and one that just guesses randomly.

The core problem bipartite checking solves is this: can you divide the nodes of a graph into exactly two groups such that every edge crosses from one group to the other? No edge should connect two nodes inside the same group. This property is what makes matching algorithms (like pairing job applicants to job openings) efficient, and it's why databases use it to optimize JOIN operations under the hood.

By the end of this article you'll understand not just how to implement a bipartite check using both BFS and DFS, but why the 2-coloring trick works mathematically, what disconnected graphs mean for your algorithm, and how to handle the edge cases that trip people up in real interviews. You'll walk away with fully runnable Java code and the confidence to reason about graph coloring problems from scratch.

What is Bipartite Graph Check? — Plain English

A graph is bipartite if you can color every node with one of two colors such that no two adjacent nodes share the same color. Imagine trying to seat guests at a party where certain pairs don't get along — you put one group on the left side and another on the right, ensuring every conflict is between sides, not within. Common examples: job assignment graphs (workers on one side, jobs on the other), class scheduling (students on one side, courses on the other), and movie recommendation systems (users and movies as two distinct sets). A graph is bipartite if and only if it contains no odd-length cycle. BFS or DFS can check this in O(V+E) by attempting to 2-color the graph and failing when a conflict is found.

Production Insight
In production recommendation systems, a non-bipartite graph causes cross-contamination between users and items, generating irrelevant suggestions.
Always run the check on the full adjacency structure, not just a sample.
Rule: if your user-item graph fails bipartiteness, you likely have user-user friendships that need explicit handling.
Key Takeaway
Bipartite = no odd cycles = 2-colorable.
Common real-world graphs (users↔items, jobs↔workers) are inherently bipartite.
When they're not, you have a data model problem that needs design intervention.
Bipartite Graph Check — Disconnected Component Trap THECODEFORGE.IO Bipartite Graph Check — Disconnected Component Trap 2-coloring BFS/DFS with component-wise reset BFS Queue Coloring Assign color 0 to start, enqueue neighbors Check Neighbor Color If uncolored, assign opposite; if same, fail Component Loop Iterate all vertices; skip already colored Disconnected Component Unvisited vertex starts new BFS/DFS Bipartite Result All components 2-colored without conflict ⚠ Missing component loop yields false positive Always restart BFS/DFS for each unvisited vertex THECODEFORGE.IO
thecodeforge.io
Bipartite Graph Check — Disconnected Component Trap
Bipartite Graph Check

How Bipartite Check Works — Step by Step

  1. Initialize color array with -1 for all nodes (uncolored).
  2. For each uncolored node (to handle disconnected graphs):
  3. a. Assign color 0 to this node and add it to the BFS queue.
  4. b. While queue is not empty:
  5. i. Dequeue node u.
  6. ii. For each neighbor v of u:
  7. - If v is uncolored: color v with 1 - color[u] (opposite color), enqueue v.
  8. - If v has the same color as u: return False (not bipartite, odd cycle detected).
  9. If all nodes are colored without conflict: return True.
BipartiteCheck.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.util.*;

public class BipartiteCheck {
    public boolean isBipartite(int n, List<List<Integer>> adj) {
        int[] color = new int[n];
        Arrays.fill(color, -1);
        
        for (int i = 0; i < n; i++) {
            if (color[i] != -1) continue;
            color[i] = 0;
            Queue<Integer> queue = new LinkedList<>();
            queue.offer(i);
            
            while (!queue.isEmpty()) {
                int u = queue.poll();
                for (int v : adj.get(u)) {
                    if (color[v] == -1) {
                        color[v] = 1 - color[u];
                        queue.offer(v);
                    } else if (color[v] == color[u]) {
                        return false;  // Odd cycle detected
                    }
                }
            }
        }
        return true;
    }

    public static void main(String[] args) {
        // Example: bipartite graph; edges: 0-1,0-3,1-2,2-3,3-4
        int n = 5;
        List<List<Integer>> adj = new ArrayList<>();
        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
        adj.get(0).addAll(Arrays.asList(1,3));
        adj.get(1).addAll(Arrays.asList(0,2));
        adj.get(2).addAll(Arrays.asList(1,3));
        adj.get(3).addAll(Arrays.asList(0,2,4));
        adj.get(4).addAll(Arrays.asList(3));
        
        BipartiteCheck bc = new BipartiteCheck();
        System.out.println(bc.isBipartite(n, adj));  // true
        
        // Non-bipartite: triangle 0-1-2
        n = 3;
        adj = new ArrayList<>();
        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
        adj.get(0).addAll(Arrays.asList(1,2));
        adj.get(1).addAll(Arrays.asList(0,2));
        adj.get(2).addAll(Arrays.asList(0,1));
        System.out.println(bc.isBipartite(n, adj));  // false
    }
}
Output
true
false
Why 1 - color[u] works
  • In BFS, each level is the opposite color of the parent, exactly like alternating a parity bit.
  • If you ever see an already-colored neighbor with the same bit, you've completed an odd cycle.
  • Mathematically, bipartiteness is exactly that the graph's adjacency matrix has no odd-power cycle.
Production Insight
Queue size can grow to O(V). For massive graphs, memory usage is fine, but ensure you use an efficient queue (ArrayDeque over LinkedList).
If using recursive DFS, you risk stack overflow on deep graphs; BFS is safer for production.
Always test with a disconnected graph that has an odd cycle in some component.
Key Takeaway
BFS 2-coloring is simple: assign alternate colors as you traverse.
The entire algorithm is O(V+E) time and O(V) space.
The outer loop over all nodes handles disconnected graphs – never skip it.
BFS vs DFS for Bipartite Check
IfGraph depth > 10,000 nodes
UsePrefer BFS iterative over recursive DFS to avoid stack depth errors
IfNeed to find the odd cycle edges
UseDFS may be easier to extend to find the cycle path
IfProduction memory constraints are tight
UseBFS queue uses O(V) worst-case space; DFS recursion uses O(V) stack, but iterative DFS uses explicit stack O(V)
IfGraph is mostly trees (no cycles)
UseBoth BFS and DFS are equivalent; choose whichever fits your codebase

Worked Example — Checking a Graph for Bipartiteness

Graph: nodes 0,1,2,3,4. Edges: (0,1),(0,3),(1,2),(2,3),(3,4).

BFS from 0: color[0]=0. Queue=[0]. 1. Dequeue 0. Neighbors 1,3 uncolored → color[1]=1, color[3]=1. Queue=[1,3]. 2. Dequeue 1. Neighbor 0 (color=0≠1, OK). Neighbor 2 uncolored → color[2]=0. Queue=[3,2]. 3. Dequeue 3. Neighbor 0 (color=0≠1, OK). Neighbor 2 (color=0≠1, OK). Neighbor 4 uncolored → color[4]=0. Queue=[2,4]. 4. Dequeue 2. Neighbor 1 (color=1≠0, OK). Neighbor 3 (color=1≠0, OK). Queue=[4]. 5. Dequeue 4. Neighbor 3 (color=1≠0, OK). Queue=[]. 6. No conflicts. Return True. Bipartition: {0,2,4} and {1,3}.

Now add edge (0,2): color[0]=0, color[2]=0, same color! Not bipartite (triangle 0-1-2 is odd cycle).

Production Insight
In a production environment, manually tracing colors like this is a great debugging technique.
If you can walk through small examples before reading code, you'll catch bugs earlier.
The cool part: the same colors appear at every step – that's the invariant check.
Key Takeaway
Trace through a few small graphs by hand before coding.
The pattern: every edge must connect opposite colors.
If you see a conflict, you just found an odd cycle.

Implementation Details – Production-Grade Java Code

The implementation above (in Java) follows best practices
  • Uses adjacency list representation for O(V+E) space and O(degree) iteration.
  • Handles disconnected graphs via the outer for loop.
  • Colors with integer array for speed.
  • Returns false immediately on conflict rather than continuing.
For production, consider these enhancements
  • Use a generic graph interface to allow different storage backends.
  • If the graph is read from a database or API, validate the edge list before processing.
  • Add logging to track which component caused failure and the conflict edge.
  • For very large graphs (millions of nodes), use iterative DFS with explicit stack or parallel BFS per component.
BipartiteCheckProduction.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BipartiteCheckProduction {
    private static final Logger log = LoggerFactory.getLogger(BipartiteCheckProduction.class);

    public boolean isBipartite(int n, List<Integer>[] adj) {
        int[] color = new int[n];
        Arrays.fill(color, -1);
        
        for (int start = 0; start < n; start++) {
            if (color[start] != -1) continue;
            
            color[start] = 0;
            Queue<Integer> queue = new ArrayDeque<>();
            queue.offer(start);
            
            while (!queue.isEmpty()) {
                int u = queue.poll();
                for (int v : adj[u]) {
                    if (color[v] == -1) {
                        color[v] = 1 - color[u];
                        queue.offer(v);
                    } else if (color[v] == color[u]) {
                        log.warn("Non-bipartite: conflict between nodes {} and {} with color {}", u, v, color[u]);
                        return false;
                    }
                }
            }
        }
        return true;
    }
}
ArrayDeque vs LinkedList
For BFS, always prefer ArrayDeque over LinkedList. ArrayDeque is faster due to cache locality and has no overhead per element. In production, that micro-optimisation saves milliseconds per million nodes.
Production Insight
Logging the conflicting edge saves hours of debugging.
For graphs larger than memory, consider streaming checks via external sort – but in practice most bipartite checks run on in-memory subgraphs.
Never use adjacency matrix for sparse real-world graphs – O(V^2) memory kills servers.
Key Takeaway
Production code needs logging, validation, and efficient data structures.
ArrayDeque > LinkedList for BFS.
Immediate return on conflict is fine for existence checks, but if you need the violating cycle, extend the algorithm to backtrack.

Edge Cases and Pitfalls

Five edge cases that break naive implementations: 1. Disconnected components: As shown, iterate over all vertices. 2. Self-loop: A node connected to itself forces same color → non-bipartite immediately. 3. Graph with 0 or 1 node: Trivially bipartite (no edges). 4. Multiple edges between same nodes: Should not cause false positive but can be optimised: use Set adjacency to avoid duplicate per-tasking. 5. Directed graph: Bipartition is defined on undirected graphs. For directed, ignore direction and treat edges as undirected for coloring.

Also, do not confuse bipartite with complete bipartite. Bipartite only requires that all edges go across the two sets; no requirement that all cross-edges exist.

Don't forget self-loops
A self-loop makes a graph non-bipartite because the adjacent node is itself, forcing the same color. Always check for self-loops explicitly when ingesting edges.
Production Insight
Self-loops often creep in from data ingestion bugs – a user following themselves in a social graph.
Treat the graph as undirected: BFS neighbors must include both directions.
For directed graphs, you can add both edges from u→v and v→u, but better to explicitly undirect the check.
Key Takeaway
Edge cases: disconnected, self-loop, single node, duplicate edges, directed/undirected.
Always handle them or your bipartite check will be wrong in production.
The outer loop for disconnected graphs is not optional.

DFS Alternative – Recursive 2-Coloring

DFS works identically in logic: assign the opposite color to each unvisited neighbor, and recurse. The only difference is recursion stack vs. explicit BFS queue. Use DFS when you need to also find the odd cycle path (DFS can backtrack). For large graphs, prefer iterative BFS to avoid stack overflow.

Pseudo-code for DFS: function dfs(u, c): color[u] = c for each neighbor v: if color[v] == -1: if not dfs(v, 1-c): return false else if color[v] == c: return false return true

Call from each uncolored node: color[start] = 0; if not dfs(start, 0) return false.

BipartiteCheckDFS.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class BipartiteCheckDFS {
    private int[] color;
    private List<Integer>[] adj;
    
    public boolean isBipartite(int n, List<Integer>[] adj) {
        this.adj = adj;
        color = new int[n];
        Arrays.fill(color, -1);
        
        for (int i = 0; i < n; i++) {
            if (color[i] == -1) {
                color[i] = 0;
                if (!dfs(i)) return false;
            }
        }
        return true;
    }
    
    private boolean dfs(int u) {
        for (int v : adj[u]) {
            if (color[v] == -1) {
                color[v] = 1 - color[u];
                if (!dfs(v)) return false;
            } else if (color[v] == color[u]) {
                return false;
            }
        }
        return true;
    }
}
Production Insight
Recursive DFS is elegant but dangerous for deep graphs. In production, set stack size with -Xss if you must use recursion.
Iterative DFS with an explicit stack is safer and just as fast.
Most interviewers accept DFS; in real systems, default to BFS.
Key Takeaway
DFS and BFS are equivalent for 2-coloring.
Use BFS if you care about stack depth; use DFS if you need to recover the odd cycle path.
The coloring logic is identical – only traversal order changes.

BFS: The Queue Doesn't Lie — Why Adjacency-Level Coloring Works

The BFS approach for bipartite check isn't just another graph traversal. It's the direct answer to the question: can I separate my graph into two camps where no member of a camp shares an edge with another member of the same camp?

The logic is ruthless: assign a color to the starting node (say color 0), then every neighbor gets the opposite color (color 1). The BFS queue enforces level-by-level processing, which means any edge connecting two nodes at the same BFS level instantly reveals an odd-length cycle. That's your smoking gun — the graph fails.

Production teams prefer BFS over DFS for this specific problem because BFS guarantees you find conflicts at the shallowest depth. In a large graph with millions of vertices, BFS also avoids stack overflow that DFS recursion can trigger on deep paths. The adjacency list representation is your default choice here — it's O(V+E) space and time, no surprises. If you're seeing a Java StackOverflowError during DFS on a sparse graph with long chains, switch to BFS immediately.

Feed the graph into a queue, track colors in an integer array (0=uncolored, 1=red, -1=blue), and the moment you try to assign a color that doesn't match, return false.

BipartiteBFS.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// io.thecodeforge — dsa tutorial

import java.util.*;

public class BipartiteBFS {
    public boolean isBipartite(int[][] graph) {
        int n = graph.length;
        int[] colors = new int[n]; // 0=unvisited, 1=red, -1=blue
        
        for (int start = 0; start < n; start++) {
            if (colors[start] != 0) continue;
            
            Queue<Integer> queue = new LinkedList<>();
            colors[start] = 1;
            queue.offer(start);
            
            while (!queue.isEmpty()) {
                int current = queue.poll();
                int expectedNeighborColor = -colors[current];
                
                for (int neighbor : graph[current]) {
                    if (colors[neighbor] == 0) {
                        colors[neighbor] = expectedNeighborColor;
                        queue.offer(neighbor);
                    } else if (colors[neighbor] != expectedNeighborColor) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
}
Output
Input: [[1,3], [0,2], [1,3], [0,2]]
Output: true
Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
Output: false
Production Trap:
BFS works with disconnected components too. The outer loop over all vertices catches isolated nodes. If you skip that loop, you'll false-positive on disconnected but bipartite graphs. Don't be that engineer.
Key Takeaway
If two adjacent nodes land on the same BFS level, the graph has an odd cycle — bail out.

DFS: Recursive Coloring With Explicit Stack State

DFS for bipartite check is elegant — until it isn't. The recursion naturally follows edges deeper, coloring as it goes. If a node is already colored and the neighbor has the same color, the graph fails. The recursion backtracks, and you're done.

The WHY: DFS exploits the graph's connectivity structure. It works beautifully on trees and graphs with shallow depth. The problem? Stack depth. For a graph with a chain of 10,000 nodes, your recursion call stack eats memory proportional to the longest path. In production, that's a StackOverflowError waiting to happen. Senior engineers write the iterative DFS version with an explicit Deque stack — it's the same logic, no recursion risk.

You must pass the parent node in the recursive call to avoid re-coloring the immediate parent (which is fine — it should have the opposite color). The implementation is tight: start at node 0, color it, then for each neighbor, either recurse or check the color conflict.

Disconnected graphs? Same fix as BFS: loop over all vertices. Each uncolored node starts a new DFS component. Complexity is O(V+E) time and O(V) space for the color array plus recursion auxiliary space.

BipartiteDFS.javaJAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// io.thecodeforge — dsa tutorial

import java.util.*;

public class BipartiteDFS {
    public boolean isBipartite(int[][] graph) {
        int n = graph.length;
        int[] colors = new int[n];
        
        for (int v = 0; v < n; v++) {
            if (colors[v] == 0) {
                if (!dfsColor(graph, colors, v, 1)) {
                    return false;
                }
            }
        }
        return true;
    }
    
    private boolean dfsColor(int[][] graph, int[] colors, int node, int color) {
        colors[node] = color;
        for (int neighbor : graph[node]) {
            if (colors[neighbor] == 0) {
                if (!dfsColor(graph, colors, neighbor, -color)) {
                    return false;
                }
            } else if (colors[neighbor] == color) {
                return false;
            }
        }
        return true;
    }
}
Output
Input: [[1,2], [0,2], [0,1]]
Output: false
Input: [[1], [0,2], [1]]
Output: true
Senior Shortcut:
DFS recursion is fine for graphs under 5,000 nodes. Beyond that, always implement iterative DFS with a stack. The color logic is identical — you push (node, color) pairs onto the stack. No stack overflow, no debugging recursion depth in production.
Key Takeaway
DFS is intuitive for small graphs; iterative DFS scales. Always handle disconnected components with a loop.
● Production incidentPOST-MORTEMseverity: high

Bipartite Check Misses Conflict in Disconnected Graph

Symptom
The recommendation system incorrectly allowed connections within the same user group for certain users, leading to irrelevant suggestions.
Assumption
Developers assumed the graph was fully connected and only ran BFS from the first node.
Root cause
The bipartite check ran BFS from only one starting node. A disconnected component containing an odd cycle was never visited, so the check returned True for a non-bipartite graph.
Fix
Add an outer loop that iterates over all nodes, starting a new BFS for each uncolored component. Ensure every component is validated.
Key lesson
  • Always handle disconnected graphs by looping over all nodes and skipping already visited ones.
  • Never assume a single BFS covers the entire graph unless you know it's connected.
  • Unit tests must include graphs with multiple disconnected components, both bipartite and non-bipartite.
Production debug guideHow to find the component that breaks bipartiteness3 entries
Symptom · 01
Bipartite check returns True but you suspect it's wrong
Fix
Verify the graph is connected. If disconnected, run the check on each component separately by iterating over all nodes.
Symptom · 02
Odd cycle suspected but not detected
Fix
Manually trace colors along each cycle. Use a debug print: print each node's color when assigned, and when a conflict arises print both node IDs and their colors.
Symptom · 03
Performance drops on large graphs
Fix
Ensure adjacency list is used, not adjacency matrix. BFS should be O(V+E). If using DFS recursion, watch for stack overflow on deep graphs.
★ Bipartite Check – Quick DebugWhen your bipartite check fails or gives wrong results, run these steps.
Odd cycle not detected in a disconnected graph
Immediate action
Loop over all nodes; start BFS from each uncolored node
Commands
for each node v where color[v] == -1: runBFS(v)
print color[v] after each assignment; on conflict, print v, neighbor, colors
Fix now
Add outer loop: for (int i = 0; i < n; i++) if (color[i] == -1) { color[i]=0; bfs(i); }
Same color conflict on adjacent nodes but graph is actually bipartite+
Immediate action
Double-check edge list – possible duplicate edge or self-loop?
Commands
Check for self-loops: for each edge (u,v), if u==v graph cannot be bipartite
Remove duplicate edges: use set for adjacency list
Fix now
Self-loop detection: if (u == v) return false; Duplicate prevention: use Set<Integer>[] adj
Stack overflow due to recursive DFS+
Immediate action
Switch to iterative BFS or use an explicit stack for DFS
Commands
Define a queue: Deque<Integer> queue = new ArrayDeque<>()
BFS: while (!queue.isEmpty()) { int u = queue.poll(); for (int v : adj[u]) {...} }
Fix now
Replace recursive function with iterative BFS using a queue
BFS vs DFS for Bipartite Check
AspectBFSDFS
Space complexityO(V) queueO(V) recursion stack (can overflow on large graphs)
Ease of finding odd cycleHarder (need parent tracking)Easier (backtrack along recursion path)
Iterative implementationNaturally iterative with queueCan be iterative with explicit stack
Cache localityBetter (queue accesses consecutive nodes)Worse (deep recursion might cause cache misses)
Common choice in interviewsStandardAccepted, but watch for recursion depth

Key takeaways

1
A graph is bipartite if and only if it has no odd-length cycles
equivalent to being 2-colorable.
2
BFS 2-coloring detects bipartiteness in O(V+E) by assigning alternating colors and failing on conflicts.
3
Trees and even-cycle-only graphs are always bipartite.
4
Always loop over all nodes to handle disconnected graphs.
5
DFS works identically but may cause stack overflow on deep graphs.
6
Self-loops and duplicate edges must be handled explicitly.

Common mistakes to avoid

4 patterns
×

Memorising syntax before understanding the concept

Symptom
You can write BFS code but can't explain why odd cycles break bipartiteness. Code passes test cases but fails on edge cases like disconnected graphs.
Fix
Draw a small graph, color it by hand. Understand that every edge forces opposite colors – that's the entire invariant. Then code from that understanding.
×

Skipping practice and only reading theory

Symptom
You know the algorithm but implement it incorrectly: forget outer loop, use wrong color assignment, or handle direction wrongly.
Fix
Write code _before_ reading solutions. Run it on the examples. Then test with disconnected graphs, self-loops, and large random graphs.
×

Forgetting to handle disconnected graphs (the outer loop)

Symptom
Bipartite check returns True but a separate component has an odd cycle, causing false positive.
Fix
Always iterate over all nodes; for each uncolored start a new BFS/DFS. Add that loop even if you assume connectivity.
×

Using adjacency matrix for large graphs

Symptom
OutOfMemoryError for graphs with >10k nodes, because O(V^2) memory blows up.
Fix
Use adjacency list representation for any production graph. It's O(V+E) memory and iterates only over existing edges.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What makes a graph bipartite?
Q02SENIOR
How does BFS check bipartiteness?
Q03SENIOR
Why are graphs with odd cycles not bipartite?
Q04SENIOR
What happens if the graph is disconnected? How do you handle it?
Q05JUNIOR
Given a graph that is bipartite, find one possible bipartition (the two ...
Q01 of 05JUNIOR

What makes a graph bipartite?

ANSWER
A graph is bipartite if its vertices can be partitioned into two sets such that every edge connects a vertex from one set to the other. Equivalently, it contains no odd-length cycle. This is also called 2-colorability.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
Why does an odd cycle make a graph non-bipartite?
02
Is a tree always bipartite?
03
What are real-world applications of bipartite graphs?
04
Can a bipartite graph have multiple valid bipartitions?
05
How do you test bipartiteness in a production system with millions of nodes?
N
Naren Founder & Principal Engineer

20+ years shipping performance-critical code where algorithms decide the bill. Drawn from code that ran under real load.

Follow
Verified
production tested
May 23, 2026
last updated
1,554
articles · all by Naren
🔥

That's Graphs. Mark it forged?

6 min read · try the examples if you haven't

Previous
Cycle Detection in Graph
11 / 17 · Graphs
Next
Number of Islands Problem