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.
Method 1: BFS and state compress
BFS: queue is used to select nodes by the divergent mode.
Compress: because 1 <= n <= 12, so uint16_t or bigger type is enough, each of the bit represent whether the current node has been selected. For example, uint16_t 2 which has the binary representation 0000000000000010, means node 2 has been selected and others haven’t.
class Solution { public: int shortestPathLength(vector<vector<int>>& graph) { int n = graph.size(); // vector<vector<int>> dist(n, vector<int>(n, n + 1)); int dist[n][n]; memset(dist, 0x3f, sizeof(int) * n * n);
// Use Floyd for(int i = 0; i < n; ++i) { for(int j: graph[i]) { dist[i][j] = 1; } } for(int k = 0; k < n; ++k) { for(int i = 0; i < n; ++i) { for(int j = 0; j < n; ++j) { dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); } } } // DP method // vector<vector<int>> f(n, vector<int>(1<<n, INT_MAX / 2)); int f[n][1<<n]; memset(f, 0x3f, sizeof(int) * n * (1<<n)); for(int mask = 1; mask < (1<<n); ++mask) { if((mask & (mask - 1)) == 0) { int u = __builtin_ctz(mask); f[u][mask] = 0; } else { for(int u = 0; u < n; ++u) { if(mask & (1 << u)) { for(int v = 0; v < n; ++v) { if(mask & (1 << v) && v != u) { f[u][mask] = min(f[u][mask], f[v][mask ^ (1<<u)] + dist[v][u]); } } } } } } // Select the shorted distance int ans = INT_MAX; for(int i = 0; i < n; ++i) { ans = min(ans, f[i][(1<<n) - 1]); }