Shortest Path Visiting All Nodes

hard graph dp bfs bitmask

Problem

Given an undirected, connected graph of n nodes, return the length of the shortest path that visits every node. You may revisit nodes and start from any node.

Inputgraph = [[1,2,3],[0],[0],[0]]
Output4
One shortest tour: 1 → 0 → 2 → 0 → 3 (4 edges).

from collections import deque
def shortestPathLength(graph):
    n = len(graph)
    full = (1 << n) - 1
    seen = set()
    q = deque()
    for i in range(n):
        q.append((i, 1 << i, 0))
        seen.add((i, 1 << i))
    while q:
        node, mask, d = q.popleft()
        if mask == full: return d
        for nb in graph[node]:
            nm = mask | (1 << nb)
            if (nb, nm) not in seen:
                seen.add((nb, nm))
                q.append((nb, nm, d + 1))
    return 0
function shortestPathLength(graph) {
  const n = graph.length, full = (1 << n) - 1;
  const seen = new Set(), q = [];
  for (let i = 0; i < n; i++) {
    q.push([i, 1 << i, 0]);
    seen.add(i + ',' + (1 << i));
  }
  let head = 0;
  while (head < q.length) {
    const [node, mask, d] = q[head++];
    if (mask === full) return d;
    for (const nb of graph[node]) {
      const nm = mask | (1 << nb);
      const key = nb + ',' + nm;
      if (!seen.has(key)) { seen.add(key); q.push([nb, nm, d + 1]); }
    }
  }
  return 0;
}
class Solution {
    public int shortestPathLength(int[][] graph) {
        int n = graph.length, full = (1 << n) - 1;
        boolean[][] seen = new boolean[n][1 << n];
        Deque<int[]> q = new ArrayDeque<>();
        for (int i = 0; i < n; i++) {
            q.offer(new int[]{ i, 1 << i, 0 });
            seen[i][1 << i] = true;
        }
        while (!q.isEmpty()) {
            int[] cur = q.poll();
            int node = cur[0], mask = cur[1], d = cur[2];
            if (mask == full) return d;
            for (int nb : graph[node]) {
                int nm = mask | (1 << nb);
                if (!seen[nb][nm]) { seen[nb][nm] = true; q.offer(new int[]{ nb, nm, d + 1 }); }
            }
        }
        return 0;
    }
}
int shortestPathLength(vector<vector<int>>& graph) {
    int n = (int)graph.size(), full = (1 << n) - 1;
    vector<vector<bool>> seen(n, vector<bool>(1 << n, false));
    queue<tuple<int, int, int>> q;
    for (int i = 0; i < n; i++) { q.push({i, 1 << i, 0}); seen[i][1 << i] = true; }
    while (!q.empty()) {
        auto [node, mask, d] = q.front(); q.pop();
        if (mask == full) return d;
        for (int nb : graph[node]) {
            int nm = mask | (1 << nb);
            if (!seen[nb][nm]) { seen[nb][nm] = true; q.push({nb, nm, d + 1}); }
        }
    }
    return 0;
}
Time: O(n · 2ⁿ) Space: O(n · 2ⁿ)