Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@
* dynamicarray
* [DynamicArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java)
* graphs
* [BipartiteGraphDFSTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java)
* [BoruvkaAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java)
* [DijkstraAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java)
* [EdmondsBlossomAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,49 @@
package com.thealgorithms.datastructures.graphs;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;

/**
* Given an adjacency list of a graph adj of V no. of vertices having 0 based
* index. Check whether the graph is bipartite or not.
* This class provides a method to check if a given undirected graph is bipartite using Depth-First Search (DFS).
* A bipartite graph is a graph whose vertices can be divided into two disjoint sets such that no two vertices
* within the same set are adjacent. In other words, all edges must go between the two sets.
*
* Input : {{0, 1, 0, 1}, {1, 0, 1, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}}
* The implementation leverages DFS to attempt to color the graph using two colors. If we can color the graph such
* that no two adjacent vertices have the same color, the graph is bipartite.
*
* Output : YES
* Example:
* Input (Adjacency Matrix):
* {{0, 1, 0, 1},
* {1, 0, 1, 0},
* {0, 1, 0, 1},
* {1, 0, 1, 0}}
*
* Output: YES (This graph is bipartite)
*
* Input (Adjacency Matrix):
* {{0, 1, 1, 0},
* {1, 0, 1, 0},
* {1, 1, 0, 1},
* {0, 0, 1, 0}}
*
* Output: NO (This graph is not bipartite)
*/
public final class BipartiteGraphDFS {
private BipartiteGraphDFS() {
}

/**
* Helper method to perform DFS and check if the graph is bipartite.
*
* During DFS traversal, this method attempts to color each vertex in such a way
* that no two adjacent vertices share the same color.
*
* @param v Number of vertices in the graph
* @param adj Adjacency list of the graph where each index i contains a list of adjacent vertices
* @param color Array to store the color assigned to each vertex (-1 indicates uncolored)
* @param node Current vertex being processed
* @return True if the graph (or component of the graph) is bipartite, otherwise false
*/
private static boolean bipartite(int v, ArrayList<ArrayList<Integer>> adj, int[] color, int node) {
if (color[node] == -1) {
color[node] = 1;
Expand All @@ -35,11 +61,16 @@ private static boolean bipartite(int v, ArrayList<ArrayList<Integer>> adj, int[]
return true;
}

/**
* Method to check if the graph is bipartite.
*
* @param v Number of vertices in the graph
* @param adj Adjacency list of the graph
* @return True if the graph is bipartite, otherwise false
*/
public static boolean isBipartite(int v, ArrayList<ArrayList<Integer>> adj) {
// Code here
int[] color = new int[v + 1];
Arrays.fill(color, -1);

for (int i = 0; i < v; i++) {
if (color[i] == -1) {
if (!bipartite(v, adj, color, i)) {
Expand All @@ -49,33 +80,4 @@ public static boolean isBipartite(int v, ArrayList<ArrayList<Integer>> adj) {
}
return true;
}

public static void main(String[] args) throws IOException {
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(read.readLine().trim());
while (t-- > 0) {
String[] str1 = read.readLine().trim().split(" ");
int numVertices = Integer.parseInt(str1[0]);
int numEdges = Integer.parseInt(str1[1]);

ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
for (int i = 0; i < numVertices; i++) {
adj.add(new ArrayList<>());
}
for (int i = 0; i < numEdges; i++) {
String[] str2 = read.readLine().trim().split(" ");
int vertexU = Integer.parseInt(str2[0]);
int vertexV = Integer.parseInt(str2[1]);
adj.get(vertexU).add(vertexV);
adj.get(vertexV).add(vertexU);
}

boolean ans = isBipartite(numVertices, adj);
if (ans) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.thealgorithms.datastructures.graphs;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.ArrayList;
import org.junit.jupiter.api.Test;

public class BipartiteGraphDFSTest {

// Helper method to create an adjacency list from edges
private ArrayList<ArrayList<Integer>> createAdjacencyList(int numVertices, int[][] edges) {
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
for (int i = 0; i < numVertices; i++) {
adj.add(new ArrayList<>());
}
for (int[] edge : edges) {
int vertexU = edge[0];
int vertexV = edge[1];
adj.get(vertexU).add(vertexV);
adj.get(vertexV).add(vertexU);
}
return adj;
}

@Test
public void testBipartiteGraphEvenCycle() {
int numVertices = 4;
int[][] edges = {{0, 1}, {1, 2}, {2, 3}, {3, 0}}; // Even cycle
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (even cycle)");
}

@Test
public void testBipartiteGraphOddCycle() {
int numVertices = 5;
int[][] edges = {{0, 1}, {1, 2}, {2, 0}, {1, 3}, {3, 4}}; // Odd cycle
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
assertFalse(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should not be bipartite (odd cycle)");
}

@Test
public void testBipartiteGraphDisconnected() {
int numVertices = 6;
int[][] edges = {{0, 1}, {2, 3}, {4, 5}}; // Disconnected bipartite graphs
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (disconnected)");
}

@Test
public void testBipartiteGraphSingleVertex() {
int numVertices = 1;
int[][] edges = {}; // Single vertex, no edges
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (single vertex)");
}

@Test
public void testBipartiteGraphCompleteBipartite() {
int numVertices = 4;
int[][] edges = {{0, 2}, {0, 3}, {1, 2}, {1, 3}}; // K2,2 (Complete bipartite graph)
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
assertTrue(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should be bipartite (complete bipartite)");
}

@Test
public void testBipartiteGraphNonBipartite() {
int numVertices = 3;
int[][] edges = {{0, 1}, {1, 2}, {2, 0}}; // Triangle (odd cycle)
ArrayList<ArrayList<Integer>> adj = createAdjacencyList(numVertices, edges);
assertFalse(BipartiteGraphDFS.isBipartite(numVertices, adj), "Graph should not be bipartite (triangle)");
}
}