Easy to understand solution in C++ using BFS with Explanation.
Intuition\n\n- Given a matrix with numbers.\n- 0 is forbidden\n- 1 is final state for all.\n- Other integers are trees which are to be cut down from smallest to
# Intuition\n\n- Given a matrix with numbers.\n- 0 is forbidden\n- 1 is final state for all.\n- Other integers are trees which are to be cut down from smallest to tallest (will need to sort)\n- Shortest path calculated using some path planning algorithm (BFS, DFS or A-star)\n\n# Approach\n\n### Forest Problem Approch\n\nIterate over the matrix and store all values greater than $1$ in a sorted manner as we are moving from smallest to tallest.\n\nAlso we need the location of the smallest tree as we will have to traverse to that location from our start point $(0,0)$. As we need a co-relation between location and tree size an ordered map is a good choice as it will sort it for us.\n\nWhile map is not empty get the smallest tree (i.e. `map.begin()`) and find the shortest path to this tree from our current position.\n\nCalculate the distance from current location to the tree using BFS and add it to the total distance travelled. If it is not reachable `return -1;` and exit from the program. \n\nRemove this tree from the map as we have cut it down once we reach  it and update our current location.\n\n### BFS Approach\n\nCreate another matrix of the same size to keep a record of the visited nodes.\n\nCreate a queue and add current location to it. While qeueue is not empty find valid neighbours mark them as visited and push them to the queue. We store the size of the queue before finding the neighbours to record the distance as all the neighbours will have the same distance (Level Order Traversal).\n\nIncrement the distance once all the nodes in a level are visited. if the queue is not empty repeat the process. Check if the newly poped node is our destination. if yes return the distance, else continue.\n\nIf queue is empty and destination node hasn\'t been reached yet return -1 as it cannnot be reached.\n\n# Complexity\n\n### Time complexity\n    \n1. Insertion of each element in map is $O(log(n))$ for $n \\times m$ trees it will take $O((n \\times m) \\cdot log(n))$.\n2. While loop execution + BFS $O((n \\times m)^2)$\n        - While loop running till map is empty takes time $O(n \\times m)$ as there are a maximum of nxm trees.\n        - BFS takes $O(n \\times m)$ as there are $n \\times m$ nodes to traverse.\n\nTotal Time Complexity $O((n \\times m)^2)$\n\n### Space complexity:\n1. Space required by map $O(n \\times m)$\n2. Space required by visited matrix $O(n \\times m)$\n3. Space required by queue in worst case $O(n \\times m)$\n\nTotal Space Complexity $O(n \\times m)$\n\n# Code\n```cpp []\nclass Solution {\npublic:\n    \n    int cutOffTree(vector<vector<int>>& forest) {\n        map<int, vector<int>> trees;\n\n        // find location of all trees to cut\n        for(int i = 0; i < forest.size(); i++){\n            for(int j = 0; j<forest[0].size(); j++){\n                if(forest[i][j] > 1) trees[forest[i][j]] = {i,j};\n            }\n        }\n        \n        int total_distance = 0;\n        \n        vector<int> current_location{0,0};\n        //find path to smallest tree.\n        while(!trees.empty()){\n            // ordered map begins with smallest key\n            vector<int> smallest_tree_location = trees.begin()->second; //get location of smallest tree\n            trees.erase(trees.begin());\n            int distance = bfs(forest, current_location, smallest_tree_location);\n            if(distance < 0) return -1;\n            total_distance += distance;\n            current_location = smallest_tree_location;\n        }\n        \n        return total_distance;\n    }\n    \n    \n    int bfs(vector<vector<int>>& grid, vector<int> start, vector<int>end){\n        \n        int rows = grid.size();\n        int cols = grid[0].size();\n        \n        vector<vector<int>> visited(rows, vector<int>(cols, 0));        \n        \n        int distance = 0;\n        \n        queue<pair<int,int>> q;\n        \n        q.push(make_pair(start[0],start[1]));\n        \n        while(!q.empty()){\n            int size = q.size();\n            \n            // Distance increments after each level\n            while(size--){\n                auto loc = q.front();\n                q.pop();\n                \n                // Access pair contents using inbuilt methods first and second\n                if(loc.first == end[0] && loc.second == end[1]) return distance;\n                \n                // move up\n                if(loc.first != 0){\n                    if(grid[loc.first-1][loc.second] != 0 && visited[loc.first-1][loc.second] == 0){\n                        visited[loc.first-1][loc.second] = 1;\n                        q.push(make_pair(loc.first-1,loc.second));\n                    }\n                }\n\n                // move down\n                if(loc.first != rows-1){\n                    if(grid[loc.first+1][loc.second] != 0 && visited[loc.first+1][loc.second] == 0){\n                        visited[loc.first+1][loc.second] = 1;\n                        q.push(make_pair(loc.first+1,loc.second));\n                    }\n                }\n\n                // move left\n                if(loc.second != 0){\n                    if(grid[loc.first][loc.second-1] != 0 && visited[loc.first][loc.second-1] == 0){\n                        visited[loc.first][loc.second-1] = 1;\n                        q.push(make_pair(loc.first,loc.second-1));\n                    }\n                }\n\n                // move right\n                if(loc.second != cols-1){\n                    if(grid[loc.first][loc.second+1] != 0 && visited[loc.first][loc.second+1] == 0){\n                        visited[loc.first][loc.second+1] = 1;\n                        q.push(make_pair(loc.first,loc.second+1));\n                    }\n                }\n            }\n            distance++;\n        }\n        \n        return -1;\n    }\n};\n```
['Array', 'Breadth-First Search', 'Queue', 'Matrix', 'C++']