Modified Dijkstra with Clear Data Structure Definition
Intuition\nBased on the fact that there may be a gap build by large enter time limit, it\'s easy to see that standard DFS/BFS mechanism may not work well, as a 
# Intuition\nBased on the fact that there may be a gap build by large enter time limit, it\'s easy to see that standard DFS/BFS mechanism may not work well, as a "detour" may be welcomed. Example:\n\n```\n[\n    [0, 100, 0, 0, 0],\n    [0, 0, 0, 100, 0]\n]\n```\n\nThe path would go in a strange way, with down step first and then another up step:\n```\n(0, 0) -> (0, 1) -> (1, 1) -> (1, 2) -> (0, 2) -> (0, 3) -> (0, 4) -> (1, 4)\n```\n\nIn this case, Dijkstra should be the recommended approach, as Dijkstra has the capability to select from the "smallest from the beginning" for each of the iteration, thus bypass the "large block" and achieve detour.\n\nHowever, Dijkstra\'s algorithm may need to be slightly modified, as "smallest" can come from two different sources in this variant of the question - which is either a step of 1, or a step of 2. It means it may still be worthwhile to visit a node twice, in order to reach a smaller +1 step, instead of a larger +2 step, in the next iteration.  \n\n# Approach\n\nDefine `result_map` data structure to hold the current minimum value. This is similar to Dijkstra\'s algorithm\'s original concept of where a "determined value" may be placed, through constantly providing a smaller alertnative from it once a new vertex is populated from a heap and may provide a smaller distance to it.\n\nHowever, the "determined value" will have to take two value: either arrived with one step, which is `min_dist_arrive_1`, or arrived with two step, which is `min_dist_arrive_2`, and update will happen as long as one of such value can be updated to a more ideal value.\n\nTo support the population of such data structure, we need to create a heap.\n\nWe define the heap as `(min_dist, uuid, (min_dist_arrive_1, min_dist_arrive_2), (x, y))`. The `min_dist` is the key element being used to prioritized processing the smallest element, and the `uuid` is just a comparison provide to break even without the need to involve comparison within `(min_dist_arrive_1, min_dist_arrive_2)` where one of them can be `None` and is not supported by Python heap\'s built in comparison function for comparison.\n\n# Complexity\n- Time complexity:\n$$O(n \\times m \\times log(n \\times m))$$\nThe heap size is bounded by the number of walls, which is equivalent to our "edge" here, as similar to Dijkstra, we never visit an edge twice. And the number of edges in the system is $$2 \\times (n - 1) \\times (m - 1) + (n - 1) + (m - 1)$$ which is roughly $$O(n \\times m)$$\n\n- Space complexity:\n$$O(n \\times m)$$\nThe heap size, plus the result map\n\n# Code\n```python3 []\nimport heapq\n\nclass Solution:\n    def minTimeToReach(self, moveTime: List[List[int]]) -> int:\n        n = len(moveTime)\n        m = len(moveTime[0])\n        \n        # format:\n        # (min_dist_arrive_1, min_dist_arrive_2)\n        result_map = [[(None, None) for j in range(m)] for i in range(n)]\n        result_map[0][0] = (None, 0)\n\n        uuid = 0\n        # format:\n        # (min_dist, uuid, (min_dist_arrive_1, min_dist_arrive_2), (x, y))\n        dj_heap = [(0, uuid, (None, 0), (0, 0))]\n\n        while len(dj_heap) > 0:\n            min_dist, _, dist_array, pos_array = heapq.heappop(dj_heap)\n\n            dist_1, dist_2 = dist_array\n            x, y = pos_array\n\n            if (x, y) == (n - 1, m - 1):\n                return min_dist\n\n            for delta_x, delta_y in [(0, 1), (1, 0), (0, -1), (-1, 0)]:\n                next_x = x + delta_x\n                next_y = y + delta_y\n\n                if next_x < n and next_y < m and next_x >= 0 and next_y >= 0:    \n                    new_dist_1 = None\n                    new_dist_2 = None\n\n                    if dist_1 is not None:\n                        new_dist_2 = max(dist_1 + 2, moveTime[next_x][next_y] + 2)\n                    if dist_2 is not None:\n                        new_dist_1 = max(dist_2 + 1, moveTime[next_x][next_y] + 1)\n                    \n                    new_min_dist = self.adaptiveMin(new_dist_1, new_dist_2)\n\n                    old_dist_1, old_dist_2 = result_map[next_x][next_y]\n\n                    if self.adpativeSmall(new_dist_1, old_dist_1) or self.adpativeSmall(new_dist_2, old_dist_2):\n                        uuid += 1\n\n                        heapq.heappush(dj_heap, (new_min_dist, uuid, (new_dist_1, new_dist_2), (next_x, next_y)))\n\n                        result_map[next_x][next_y] = (self.adaptiveMin(new_dist_1, old_dist_1), self.adaptiveMin(new_dist_2, old_dist_2))\n\n\n    def adaptiveMin(self, x1, x2):\n        if x1 is None:\n            return x2\n        if x2 is None:\n            return x1\n        return min(x1, x2)\n\n    def adpativeSmall(self, x1, x2):\n        if x1 is None and x2 is None:\n            return False\n        if x1 is None:\n            return False\n        if x2 is None:\n            return True\n        return x1 < x2\n```
['Python3']