classSolution { private: vector<int> dist; int m; int n; intf(int start, int end){ //计算曼哈顿距离 int x1 = start / n; int y1 = start % n; int x2 = end / n; int y2 = end % n; returnabs(x1 - x2) + abs(y1 - y2); } intAStar(int start, int end, vector<vector<int>>& forest){ priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; q.push({ f(start,end),start }); fill(dist.begin(), dist.end(), INT_MAX); dist[start] = 0; vector<int> dirs = { -1,0,1,0,-1 }; while (!q.empty()) { //每轮从优先队列中弹出到起点和终点距离之和最短的点进行扩展。 int state = q.top().second; q.pop(); if (state == end) return dist[state]; for (int i = 0; i < 4; i++) { int x = state / n + dirs[i]; int y = state % n + dirs[i + 1]; if (0 <= x && x<m && 0 <= y && y < n && forest[x][y]>0 && dist[x * n + y]>dist[state] + 1) { /* 如果当前节点已经被查找到过(即已经记录过dist值), * 并且当前计算的到起点的距离比此前查到的距离更短, * 就用当前的距离值代替原来的距离值,并将其放回到优先队列。 */ dist[x * n + y] = dist[state] + 1; q.push({ dist[x * n + y] + f(x * n + y,end),x * n + y }); } } } return-1; } public: intcutOffTree(vector<vector<int>>& forest){ m = forest.size(); n = forest[0].size(); dist.resize(m * n); vector<pair<int, int>> trees; 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 * n + j }); } } } sort(trees.begin(), trees.end()); int start = 0; int res = 0; for (pair<int, int> tree : trees) { int end = tree.second; int subdist = AStar(start, end, forest); if (subdist == -1) return-1; else res += subdist; start = end; } return res; } };