#847
Hard Algorithms Shortest path visiting all nodes
Dynamic Programming Bit Manipulation Breadth-First Search Graph Theory Bitmask
65.8% acceptance
Feb 22, 2026
4614
181
You have an undirected, connected graph of n nodes labeled from 0 to n - 1. You are given an array graph where graph[i] is a list of all the nodes connected with node i by an edge.
Return the length of the shortest path that visits every node. You may start and stop at any node, you may revisit nodes multiple times, and you may reuse edges.
Solution
Rust
Time O(n * m)
Space O(n * m)
/*
* You have an undirected, connected graph of n nodes labeled from 0 to n - 1. You are given an array graph where graph[i] is a list of all the nodes connected with node i by an edge.
* Return the length of the shortest path that visits every node. You may start and stop at any node, you may revisit nodes multiple times, and you may reuse edges.
* Example 1:
* Input: graph = [[1,2,3],[0],[0],[0]]
* Output: 4
* Explanation: One possible path is [1,0,2,0,3]
* Example 2:
* Input: graph = [[1],[0,2,4],[1,3,4],[2],[1,2]]
* Output: 4
* Explanation: One possible path is [0,1,4,2,3]
* Constraints:
* n == graph.length
* 1 <= n <= 12
* 0 <= graph[i].length < n
* graph[i] does not contain i.
* If graph[a] contains b, then graph[b] contains a.
* The input graph is always connected.
*/
use std::collections::VecDeque;
impl Solution {
pub fn shortest_path_length(graph: Vec<Vec<i32>>) -> i32 {
let n = graph.len();
let full = (1 << n) - 1;
let mut visited = vec![vec![false; 1 << n]; n];
let mut queue = VecDeque::new();
for i in 0..n {
let mask = 1 << i;
queue.push_back((i, mask, 0i32));
visited[i][mask] = true;
}
while let Some((node, mask, dist)) = queue.pop_front() {
if mask == full { return dist; }
for &next in &graph[node] {
let next = next as usize;
let new_mask = mask | (1 << next);
if !visited[next][new_mask] {
visited[next][new_mask] = true;
queue.push_back((next, new_mask, dist + 1));
}
}
}
0
}
}