Problem p01453 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

typedef long double real;
const real inf = 1e20;

struct point {
  int x, y;
};

int dx[] = {-1, 0, 0, 1};
int dy[] = {0, -1, 1, 0};

vector<real> dist;
// ret1: true if arg e < calculated e
// ret2: expected s-g value if e is correct
pair<bool, real> is_lower(const real e, const vector<vector<char>> &f,
                          const point &s, const point &g,
                          const vector<point> &spring) {
  const int w = f[0].size(), h = f.size();

  dist.resize(w * h);
  fill(dist.begin(), dist.end(), inf);

  queue<pair<point, real>> q;

  q.push(make_pair(g, 0));

  while (!q.empty()) {

    const auto vd = q.front();
    const auto v = vd.first;
    const auto d = vd.second;
    q.pop();
    const int idx = v.x * w + v.y;

    if (dist[idx] < inf)
      continue;
    dist[idx] = d;

    for (int dir = 0; dir < 4; ++dir) {
      const int nx = v.x + dx[dir], ny = v.y + dy[dir];
      const point vvv = {nx, ny};
      if (nx < 0 || nx >= h || ny < 0 || ny >= w)
        continue;
      char c = f[nx][ny];
      if (c == '#' || c == '*')
        continue;
      q.push(make_pair(vvv, d + 1));
    }
  }

  for (auto sp : spring)
    q.push(make_pair(sp, e));

  while (!q.empty()) {
    const auto vd = q.front();
    const auto v = vd.first;
    const auto d = vd.second;
    q.pop();
    const int idx = v.x * w + v.y;

    if (dist[idx] <= d)
      continue;
    dist[idx] = d;

    for (int dir = 0; dir < 4; ++dir) {
      const int nx = v.x + dx[dir], ny = v.y + dy[dir];
      const point vvv = {nx, ny};
      if (nx < 0 || nx >= h || ny < 0 || ny >= w)
        continue;
      char c = f[nx][ny];
      if (c == '#' || c == '*')
        continue;
      q.push(make_pair(vvv, d + 1));
    }
  }

  real total = 0;
  int count = 0;

  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {

      char c = f[i][j];
      const int idx = i * w + j;

      if (c == '#' || c == 'g' || c == '*')
        continue;

      total += dist[idx];
      count += 1;
    }
  }

  bool ok = e < total / count;
  real ans = dist[s.x * w + s.y];

  return make_pair(ok, ans);
}

int main() {
  int w, h;
  vector<vector<char>> f;

  scanf("%d%d", &w, &h);
  f.resize(h);
  for (int i = 0; i < h; ++i) {
    char buf[1024];
    scanf("%s", buf);
    for (int j = 0; buf[j] != '\\0'; ++j)
      f[i].push_back(buf[j]);
  }

  vector<point> spring;
  point s, g;

  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {

      char c = f[i][j];
      if (c == 's')
        s = {i, j};
      else if (c == 'g')
        g = {i, j};
      else if (c == '*')
        spring.push_back({i, j});
    }
  }

  real lb = 0, ub = inf / 2;
  real ans = 0;
  const int max_step = 200;

  for (int step = 0; step < max_step; ++step) {

    real mid = (lb + ub) / 2;

    auto ret = is_lower(mid, f, s, g, spring);
    if (ret.first)
      lb = mid;
    else
      ub = mid;
    ans = ret.second;
  }

  printf("%.20Lf\\n", ans);

  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

const int inf = (int)1e8;

struct point {
  int x, y;
};

int dx[] = {-1, 0, 0, 1};
int dy[] = {0, -1, 1, 0};

vector<double> dist;
// ret1: true if arg e < calculated e
// ret2: expected s-g value if e is correct
pair<bool, double> is_lower(const double e, const vector<vector<char>> &f,
                            const point &s, const point &g,
                            const vector<point> &spring) {
  const int w = f[0].size(), h = f.size();

  dist.resize(w * h);
  fill(dist.begin(), dist.end(), inf);

  queue<pair<point, double>> q;

  q.push(make_pair(g, 0));

  while (!q.empty()) {

    const auto vd = q.front();
    const auto v = vd.first;
    const auto d = vd.second;
    q.pop();
    const int idx = v.x * w + v.y;

    if (dist[idx] < inf)
      continue;
    dist[idx] = d;

    for (int dir = 0; dir < 4; ++dir) {
      const int nx = v.x + dx[dir], ny = v.y + dy[dir];
      const point vvv = {nx, ny};
      if (nx < 0 || nx >= h || ny < 0 || ny >= w)
        continue;
      char c = f[nx][ny];
      if (c == '#' || c == '*')
        continue;
      q.push(make_pair(vvv, d + 1));
    }
  }

  for (auto sp : spring)
    q.push(make_pair(sp, e));

  while (!q.empty()) {

    const auto vd = q.front();
    const auto v = vd.first;
    const auto d = vd.second;
    q.pop();
    const int idx = v.x * w + v.y;

    if (dist[idx] < d)
      continue;
    dist[idx] = d;

    for (int dir = 0; dir < 4; ++dir) {
      const int nx = v.x + dx[dir], ny = v.y + dy[dir];
      const point vvv = {nx, ny};
      if (nx < 0 || nx >= h || ny < 0 || ny >= w)
        continue;
      char c = f[nx][ny];
      if (c == '#' || c == '*')
        continue;
      q.push(make_pair(vvv, d + 1));
    }
  }

  double total = 0;
  int count = 0;

  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {

      char c = f[i][j];
      const int idx = i * w + j;

      if (c == '#' || c == 'g' || c == '*')
        continue;

      total += dist[idx];
      count += 1;
    }
  }

  bool ok = e < total / count;
  double ans = dist[s.x * w + s.y];

  return make_pair(ok, ans);
}

int main() {
  int w, h;
  vector<vector<char>> f;

  scanf("%d%d", &w, &h);
  f.resize(h);
  for (int i = 0; i < h; ++i) {
    char buf[1024];
    scanf("%s", buf);
    for (int j = 0; buf[j] != '\\0'; ++j)
      f[i].push_back(buf[j]);
  }

  vector<point> spring;
  point s, g;

  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {

      char c = f[i][j];
      if (c == 's')
        s = {i, j};
      else if (c == 'g')
        g = {i, j};
      else if (c == '*')
        spring.push_back({i, j});
    }
  }

  double lb = 0, ub = 1e10;
  double ans = 0;
  const int max_step = 100;

  for (int step = 0; step < max_step; ++step) {

    double mid = (lb + ub) / 2;

    auto ret = is_lower(mid, f, s, g, spring);
    if (ret.first)
      lb = mid;
    else
      ub = mid;
    ans = ret.second;
  }

  printf("%.20lf\\n", ans);

  return 0;
}