Leetcode 317. Shortest Distance from All Buildings

来源:互联网 发布:数控铣床自动编程软件 编辑:程序博客网 时间:2024/06/07 13:56
#include <vector>#include <iostream>#include <climits>#include <queue>using namespace std;/*  You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right. You are given a 2D grid of values 0, 1 or 2, where:Each 0 marks an empty land which you can pass by freely.Each 1 marks a building which you cannot pass through.Each 2 marks an obstacle which you cannot pass through.For example, given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2):1 - 0 - 2 - 0 - 1|   |   |   |   |0 - 0 - 0 - 0 - 0|   |   |   |   |0 - 0 - 1 - 0 - 0The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal. So return 7.Note:There will be at least one building. If it is not possible to build such house according to the above rules, return -1.*//*Analyze:   we start from "1" value and write down the steps to reach each node. If the node is reachable, we remember the reachable status as "-1". Thus, we need to maintain two tables. One is to remember the steps, the other to remember the reachable status.*/// canAchieve value mark the achievable nodes layerly. If the node is not achievable, it will always be '0'.void BFS(vector< vector<int> >& grid, int i, int j, vector< vector<int> >& steps, vector< vector<int> >& canReach, int& canAchieve) {  int m = grid.size();  int n = grid[0].size();  struct posAndStep {    int x;    int y;    posAndStep(int k, int h) : x(k), y(h) {};  };  vector< vector<int> > tmpStep(m, vector<int>(n, 0));  vector< vector<int> > dir {  {0, 1},  {0, -1},  {1, 0},  {-1, 0}};  queue<posAndStep> nodes;  posAndStep start(i, j);  nodes.push(start);  while(!nodes.empty()) {    auto curr = nodes.front();    nodes.pop();    for(auto direction : dir) {      int next_x = curr.x + direction[0];      int next_y = curr.y + direction[1];      if(next_x < m && next_x >= 0 && next_y < n && next_y >= 0 && (canReach[next_x][next_y] == canAchieve)) {        --canReach[next_x][next_y];        posAndStep next_node(next_x, next_y);        tmpStep[next_x][next_y] = tmpStep[curr.x][curr.y] + 1;        steps[next_x][next_y] += tmpStep[next_x][next_y];        nodes.push(next_node);      }    }  }  --canAchieve;}int shortestDistance(vector< vector<int> >& grid) {  if(grid.size() == 0 || grid[0].size() == 0) return 0;  int m = grid.size();  int n = grid[0].size();  vector< vector<int> > steps(m, vector<int>(n, 0));  vector< vector<int> > canReach = grid;  // BFS to cacualte the step and remember the status.  int canAchieve = 0;  for(int i = 0; i < m; ++i) {    for(int j = 0; j < n; ++j) {      if(grid[i][j] == 1) {        BFS(grid, i, j, steps, canReach, canAchieve);      }    }  }  int minDistant = INT_MAX;  for(int i = 0; i < m; ++i) {    for(int j = 0; j < n; ++j) {      if(steps[i][j] && canReach[i][j]) {        minDistant = min(minDistant, steps[i][j]);      }    }  }  return minDistant;}int main(void) {  vector< vector<int> > matrix{    {1, 0, 2, 0, 1},    {0, 0, 0, 0, 0},    {0, 0, 1, 0, 0}};  cout << shortestDistance(matrix) << endl;}

0 0
原创粉丝点击