Official

G - Escape Route Editorial by en_translator


This problem features BFS (Breadth-First Search) with multiple starting points.

We compute the distance from each corridor cell \((i, j)\) to a nearest exit. This can be done by this way:

  • First, set \(d(i, j) = \infty\) for every cell,
  • Inspect every cell \((i, j)\). If it is an emergency exit, set \(d(i, j) = 0\).
  • Perform a BFS starting from all emergency-exit cells.

While performing BFS, we also record for each cell “the previous cell before reaching that cell.” The arrows obtained like this always satisfy the conditions in the problem statement by the property of shortest distance.

The problem can be solved by appropriately implementing this procedure. The complexity is \(\mathrm{O}(HW)\), which is fast enough.

  • Sample code (C++)
#include <iostream>
#include <queue>
#include <string>
using namespace std;

int main() {
  int H, W;
  cin >> H >> W;
  vector<string> S(H);
  for (auto& s : S) cin >> s;

  queue<pair<int, int>> Q;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (S[i][j] == 'E') Q.emplace(i, j);
    }
  }
  int dx[] = {1, 0, -1, 0};
  int dy[] = {0, 1, 0, -1};
  auto ok = [&](int i, int j) { return 0 <= i and i < H and 0 <= j and j < W; };
  string A = "^<v>";
  while (!Q.empty()) {
    auto [i, j] = Q.front();
    Q.pop();
    for (int k = 0; k < 4; k++) {
      int ni = i + dx[k];
      int nj = j + dy[k];
      if (!ok(ni, nj)) continue;
      if (S[ni][nj] != '.') continue;
      S[ni][nj] = A[k];
      Q.emplace(ni, nj);
    }
  }

  for (auto& s : S) cout << s << "\n";
}

posted:
last update: