[dart] PriorityQueue, Go and Back step solution
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```dart []\nclass Solution {\n  int minimumTime(List<List<int>> grid) {\n    final dir = [(0, -1), (0, 1), (-1, 0), (1, 0)];\n    final n = grid.length, m = grid[0].length;\n    final dp = List.generate(n, (_) => List.filled(m, 10000000001));\n    final pq = PriorityQueue<(int, int, int)>((a, b) => a.$3.compareTo(b.$3));\n    pq.add((0,0,0));\n    while (!pq.isEmpty){\n        final (y, x, t) = pq.remove();\n        // The count of next cells that we can reach from current cell.\n        final canReach = dir.map((a) => (a.$1 + y, a.$2 + x))\n                            .where((a) => !(a.$1 < 0 || a.$1 >= n || a.$2 < 0 || a.$2 >= m))\n                            .where((a) => grid[a.$1][a.$2] <= t + 1)\n                            .length;\n        for (final (dy, dx) in dir){\n            int ny = y + dy, nx = x + dx, nt = t + 1;\n            if (ny < 0 || ny >= n || nx < 0 || nx >= m) continue;\n            if (nt < grid[ny][nx]){\n                if (canReach == 0) continue;\n                // if cells we can reach > 0\n                // we can increase time by go and back step\n                // +2 time each go and back\n                int diff = grid[ny][nx] - nt;\n                if (diff % 2 == 1) diff++;\n                nt += diff;\n            }\n            if (dp[ny][nx] <= nt) continue;\n            dp[ny][nx] = nt;\n            pq.add((ny, nx, nt));\n        }\n    }\n    final res = dp.last.last;\n    if (res == 10000000001) return -1;\n    return res;\n  }\n}\n\n\nclass PriorityQueue<T> { \n\tList<T> _elements = []; \n\tComparator<T> _comparator; \n\tPriorityQueue(this._comparator); \n\t\n\tvoid add(T element) { \n\t\t_elements.add(element); \n\t\t_bubbleUp(_elements.length - 1); \n\t} \n\t\n\tT remove() { \n\t\tif (isEmpty) throw StateError("Cannot remove from empty priority queue."); \n\t\tT result = _elements.first; \n\t\tif (_elements.length == 1) { \n\t\t\t_elements.removeLast(); \n\t\t} else { \n\t\t\t_elements[0] = _elements.removeLast(); \n\t\t\t_bubbleDown(0); \n\t\t} return result; \n\t} \n\t\t\n\tT get first { \n\t\tif (isEmpty) throw StateError(\'empty\'); \n\t\treturn _elements.first; \n\t} \n\tbool get isNotEmpty => !_elements.isEmpty; \n\tbool get isEmpty => _elements.isEmpty; \n\t\n\tint get length => _elements.length; \n\t\n\tvoid _bubbleUp(int index) { \n\t\twhile (index > 0) { \n\t\t\tint parent = (index - 1) >> 1; \n\t\t\tif (_comparator(_elements[index], _elements[parent]) >= 0) break; \n\t\t\t_swap(index, parent); index = parent; \n\t\t} \n\t} \n\t\n\tvoid _bubbleDown(int index) { \n\t\tint leftChild; \n\t\tint rightChild; \n\t\tint minChild; \n\t\twhile (true) { \n\t\t\tleftChild = (index << 1) + 1; \n\t\t\trightChild = leftChild + 1; \n\t\t\tminChild = index; \n\t\t\tif (leftChild < _elements.length && _comparator(_elements[leftChild], _elements[minChild]) < 0) { \n\t\t\t\tminChild = leftChild; \n\t\t\t} \n\t\t\tif (rightChild < _elements.length && _comparator(_elements[rightChild], _elements[minChild]) < 0) { \n\t\t\t\tminChild = rightChild; \n\t\t\t} \n\t\t\tif (minChild == index) break; \n\t\t\t_swap(index, minChild); index = minChild; \n\t\t}\n\t} \n\t\n\tvoid _swap(int i, int j) { \n\t\tT temp = _elements[i]; \n\t\t_elements[i] = _elements[j]; \n\t\t_elements[j] = temp; \n\t} \n}\n```
['Dart']