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.
Solutions
Solution 1
Thinking
We want a shortest walk that visits every node; edges may be reused. \(n\le 12\), so the walk itself is not the state, but (current node, visited mask) has only \(n\cdot 2^n\) pairs.
Multi-source BFS from every start on that state space: the first time the mask is full, the layer index is the answer.
usestd::collections::VecDeque;implSolution{#[allow(dead_code)]pubfnshortest_path_length(graph:Vec<Vec<i32>>)->i32{letn=graph.len();letmutvis=vec![vec![false;1<<n];n];letmutq=VecDeque::new();// Initialize the queueforiin0..n{q.push_back(((i,1<<i),0));vis[i][1<<i]=true;}// Begin BFSwhile!q.is_empty(){let((i,st),count)=q.pop_front().unwrap();ifst==(1<<n)-1{returncount;}// If the path has not been visitedforjin&graph[i]{letnst=st|(1<<*j);if!vis[*jasusize][nst]{q.push_back(((*jasusize,nst),count+1));vis[*jasusize][nst]=true;}}}-1}}
Solution 2
Thinking
Plain BFS expands by layer. An admissible heuristic — the number of still-unvisited nodes — lets a priority queue pop \(dist+h\) first.
Relaxation is still unit-weight shortest paths, so optimality is kept; full masks tend to appear earlier once most nodes are visited.