---
# System prepended metadata

title: 'LeetCode #675 [Cut Off Trees for Golf Event](https://leetcode.com/problems/cut-off-trees-for-golf-event/)'
tags: [LeetCode, Hard, BFS, Queue]

---

###### tags: `LeetCode` `BFS` `Queue` `Hard`
# LeetCode #675 [Cut Off Trees for Golf Event](https://leetcode.com/problems/cut-off-trees-for-golf-event/)
### (Hard)

你被請來給一個要舉辦高爾夫比賽的樹林砍樹。樹林由一個 m x n 的矩陣表示， 在這個矩陣中：

0 表示障礙，無法觸碰
1 表示地面，可以行走
比 1 大的數 表示有樹的單元格，可以行走，數值表示樹的高度
每一步，你都可以向上、下、左、右四個方向之一移動一個單位，如果你站的地方有一棵樹，那麼你可以決定是否要砍倒它。

你需要按照樹的高度從低向高砍掉所有的樹，每砍過一顆樹，該單元格的值變為 1（即變為地面）。

你將從 (0, 0) 點開始工作，返回你砍完所有樹需要走的最小步數。如果你無法砍完所有的樹，返回 -1 。

可以保證的是，沒有兩棵樹的高度是相同的，並且你至少需要砍倒一棵樹。

![](https://i.imgur.com/fjHXE6z.png)    ![](https://i.imgur.com/u0zq7e5.png)

---
由於題目規定要按照樹的高度, 從矮的砍到高的, 因此先遍歷整個forest, 遇到樹時儲存{樹的高度, 列座標, 行座標}(使用tuple), 遍歷完後對樹的數組進行排序(會按照tuple的第一個數字排序, 也就是樹高)。

接下來, 從{0,0}開始(題目規定), 對每一個樹的位置進行BFS搜尋以找到最短路徑, 並將路徑長加至答案中, 而在下一輪中, 原先到達的樹的位置改為出發位置, 並再往後找下一個樹的位置(同樣使用BFS找最短路徑), 直到找到最後一個樹的位置, 並回傳加總後的答案(總路徑長)。

---
```
class Solution {
public:
    int m, n;
    int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
    int cutOffTree(vector<vector<int>>& forest) {
        vector<tuple<int, int, int>> trees;// height, x, y
        m = forest.size();
        n = forest[0].size();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(forest[i][j]>1){
                    trees.push_back({forest[i][j], i, j});
                }
            }
        }
        sort(trees.begin(), trees.end());
        int ans = 0;
        int start_x = 0;
        int start_y = 0;
        for(auto& t:trees){
            int end_x = get<1>(t);
            int end_y = get<2>(t);
            int step = bfs(forest, start_x, start_y, end_x, end_y);
            if(step==INT_MAX)return -1;
            start_x = end_x;
            start_y = end_y;
            ans+=step;
        }
        return ans;
    }
    int bfs(vector<vector<int>>& forest, int start_x, int start_y, int end_x, int end_y){
        queue<pair<int, int>> q;
        vector<vector<int>> visited(m,vector<int>(n, 0));
        q.push({start_x, start_y});
        int step = 0;
        while(!q.empty()){
            for(int i=q.size();i>0;i--){
                pair<int, int> loc = q.front();q.pop();
                int x = loc.first;
                int y = loc.second;
                if(x == end_x && y ==end_y)return step;
                for(int j=0;j<4;j++){
                    int tmp_x = x + dir[j][0];
                    int tmp_y = y + dir[j][1];
                    if(tmp_x<0||tmp_y<0||tmp_x==m||tmp_y==n||forest[tmp_x][tmp_y]==0||visited[tmp_x][tmp_y]==1)continue;
                    q.push({tmp_x, tmp_y});
                    visited[tmp_x][tmp_y] = 1;
                }
            }
            step++;
        }
        return INT_MAX;
    }
};
```