From 77ebc0944e947fc41efdc8c014853e6605774092 Mon Sep 17 00:00:00 2001 From: Lam Haoyin Date: Sat, 26 Feb 2022 17:14:18 +0800 Subject: [PATCH] add: 220226 [cpp] --- cpp/2202/220226.cpp | 101 ++++++++++++++++++++++++++++++++++++++++ cpp/2202/CMakeLists.txt | 2 +- 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 cpp/2202/220226.cpp diff --git a/cpp/2202/220226.cpp b/cpp/2202/220226.cpp new file mode 100644 index 0000000..59a3a9a --- /dev/null +++ b/cpp/2202/220226.cpp @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include + +/** + * 847. Shortest Path Visiting All Nodes + * 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. + */ + +class Solution { +private: + static void bfs(const std::vector>& G, int begin, int* ret) { + int n = G.size(); + + // Insert: (node#, length) + std::queue q; + bool* const vis = new bool[n]{}; + q.push(begin); + q.push(0); + vis[begin] = true; + + while (!q.empty()) { + int idx = q.front(); + q.pop(); + int len = q.front(); + q.pop(); + + ret[idx] = len; + + for (int i : G[idx]) { + if (!vis[i]) { + q.push(i); + q.push(1 + len); + vis[i] = true; + } + } + } + + delete[] vis; + } + + static inline constexpr int bitSetAdd(int set, int id) { + return set | (1 << id); + } + + static inline constexpr int bitSetRemove(int set, int id) { + return set & (~(1 << id)); + } + +public: + static int shortestPathLength(const std::vector>& graph) { + int n = graph.size(); + int lens[n][n]; + for (int i = 0; i < n; ++i) { + bfs(graph, i, lens[i]); + } + + // dp: let dp[visitedSet][node] be the remaining length to + // reach the all-node-visited state. + // dp[(1 << n) - 1][x] always be 0; + int dp[1 << n][n]; + std::memset(dp, -1, sizeof dp); + std::memset(dp[(1 << n) - 1], 0, sizeof dp[(1 << n) - 1]); + + // visited includes node. + std::function calc; + calc = [&](int visited, int node) { + if (dp[visited][node] != -1) + return dp[visited][node]; + + int& now = dp[visited][node]; + now = 0x7FFFFFFF; + // Try goes to next node + for (int i = 0; i < n; ++i) { + if (!(visited & (1 << i))) { + // This node not visited, goes to it + // directly regardless of nodes not + // visited along the way + now = std::min(now, lens[node][i] + calc(bitSetAdd(visited, i), i)); + } + } + + return now; + }; + + int ret = 0x7FFFFFFF; + for (int i = 0; i < n; ++i) { + ret = std::min(ret, calc(bitSetAdd(0, i), i)); + } + + return ret; + } +}; + +int main() { + std::cout << Solution::shortestPathLength({{1},{0,2,4},{1,3,4},{2},{1,2}}); + return 0; +} diff --git a/cpp/2202/CMakeLists.txt b/cpp/2202/CMakeLists.txt index a6253c0..f046b97 100644 --- a/cpp/2202/CMakeLists.txt +++ b/cpp/2202/CMakeLists.txt @@ -3,4 +3,4 @@ PROJECT(2202) SET(CMAKE_CXX_STANDARD 23) -ADD_EXECUTABLE(2202 220226-CN.cpp) +ADD_EXECUTABLE(2202 220226.cpp)