Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Create zero_one_bfs.java #6560

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
alxkm merged 7 commits into TheAlgorithms:master from ananya-research:feat
Oct 6, 2025
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
77 changes: 77 additions & 0 deletions src/main/java/com/thealgorithms/graph/ZeroOneBfs.java
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.thealgorithms.graph;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.List;

/**
* 0-1 BFS for shortest paths on graphs with edges weighted 0 or 1.
*
* <p>Time Complexity: O(V + E). Space Complexity: O(V).
*
* <p>References:
* <ul>
* <li>https://cp-algorithms.com/graph/01_bfs.html</li>
* </ul>
*/
public final class ZeroOneBfs {

private ZeroOneBfs() {
// Utility class; do not instantiate.
}

/**
* Computes shortest distances from {@code src} in a graph whose edges have weight 0 or 1.
*
* @param n the number of vertices, labeled {@code 0..n-1}
* @param adj adjacency list; for each vertex u, {@code adj.get(u)} is a list of pairs
* {@code (v, w)} where {@code v} is a neighbor and {@code w} is 0 or 1
* @param src the source vertex
* @return an array of distances; {@code Integer.MAX_VALUE} denotes unreachable
* @throws IllegalArgumentException if {@code n < 0}, {@code src} is out of range,
* or any edge has weight other than 0 or 1
*/
public static int[] shortestPaths(int n, List<List<int[]>> adj, int src) {
if (n < 0 || src < 0 || src >= n) {
throw new IllegalArgumentException("Invalid n or src");
}
int[] dist = new int[n];
Arrays.fill(dist, Integer.MAX_VALUE);
Deque<Integer> dq = new ArrayDeque<>();

dist[src] = 0;
dq.addFirst(src);

while (!dq.isEmpty()) {
int u = dq.pollFirst();
List<int[]> edges = adj.get(u);
if (edges == null) {
continue;
}
for (int[] e : edges) {
if (e == null || e.length < 2) {
continue;
}
int v = e[0];
int w = e[1];
if (v < 0 || v >= n) {
continue; // ignore bad edges
}
if (w != 0 && w != 1) {
throw new IllegalArgumentException("Edge weight must be 0 or 1");
}
int nd = dist[u] + w;
if (nd < dist[v]) {
dist[v] = nd;
if (w == 0) {
dq.addFirst(v);
} else {
dq.addLast(v);
}
}
}
}
return dist;
}
}
68 changes: 68 additions & 0 deletions src/test/java/com/thealgorithms/graph/ZeroOneBfsTest.java
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.thealgorithms.graph;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

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

class ZeroOneBfsTest {

// Helper to build adjacency list with capacity n
private static List<List<int[]>> makeAdj(int n) {
List<List<int[]>> adj = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
adj.add(new ArrayList<>());
}
return adj;
}

@Test
void simpleLineGraph() {
int n = 4;
List<List<int[]>> adj = makeAdj(n);
// 0 --0--> 1 --1--> 2 --0--> 3
adj.get(0).add(new int[] {1, 0});
adj.get(1).add(new int[] {2, 1});
adj.get(2).add(new int[] {3, 0});

int[] dist = ZeroOneBfs.shortestPaths(n, adj, 0);
assertArrayEquals(new int[] {0, 0, 1, 1}, dist);
}

@Test
void parallelEdgesPreferZero() {
int n = 3;
List<List<int[]>> adj = makeAdj(n);
// Two edges 0->1: weight 1 and weight 0. Algorithm should choose 0.
adj.get(0).add(new int[] {1, 1});
adj.get(0).add(new int[] {1, 0});
adj.get(1).add(new int[] {2, 1});

int[] dist = ZeroOneBfs.shortestPaths(n, adj, 0);
assertArrayEquals(new int[] {0, 0, 1}, dist);
}

@Test
void unreachableNodes() {
int n = 3;
List<List<int[]>> adj = makeAdj(n);
adj.get(0).add(new int[] {1, 0});
int[] dist = ZeroOneBfs.shortestPaths(n, adj, 0);
// node 2 unreachable -> Integer.MAX_VALUE
assertArrayEquals(new int[] {0, 0, Integer.MAX_VALUE}, dist);
}

@Test
void invalidArgs() {
int n = 2;
List<List<int[]>> adj = makeAdj(n);
// invalid weight
adj.get(0).add(new int[] {1, 2});
assertThrows(IllegalArgumentException.class, () -> ZeroOneBfs.shortestPaths(n, adj, 0));
// invalid src
assertThrows(IllegalArgumentException.class, () -> ZeroOneBfs.shortestPaths(n, adj, -1));
assertThrows(IllegalArgumentException.class, () -> ZeroOneBfs.shortestPaths(n, adj, 2));
}
}

AltStyle によって変換されたページ (->オリジナル) /