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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>

#define INF 1e18
using namespace std;
typedef pair<int, int> P;
typedef pair<int, P> PP;
int dx[4] = {0, -1, 0, 1};
int dy[4] = {1, 0, -1, 0};
int fie[510][510];
int dist[2][510][510];
int w, h;
vector<PP> vec;
int sx, sy, gx, gy;
typedef long long ll;

void bfs(int y = -1, int x = -1) {
  queue<P> que;
  int type = 0;
  if (y == -1)
    type = 1;
  memset(dist[type], -1, sizeof(dist[type]));
  if (type == 0) {
    dist[type][y][x] = 0;
    que.push(P(y, x));
  } else {
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (fie[i][j] == 1) {
          dist[type][i][j] = 0;
          que.push(P(i, j));
        }
      }
    }
  }
  while (que.size()) {
    P p = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int nx = p.second + dx[i], ny = p.first + dy[i];
      if (abs(fie[ny][nx]) != 1 && dist[type][ny][nx] == -1) {
        dist[type][ny][nx] = dist[type][p.first][p.second] + 1;
        que.push(P(ny, nx));
      }
    }
  }
}

ll cnt = 0;
ll all = 0;
ll okave = 0;
ll ngave = 0;

long double calc(int v) {
  if ((dist[0][sy][sx] != -1 && dist[0][sy][sx] <= dist[1][sy][sx] + v) ||
      dist[1][sy][sx] == -1)
    return dist[0][sy][sx];
  else {
    if (cnt == 0)
      return INF;
    long double va = (long double)okave / all;
    va *= (double)1.0 * all / cnt;
    long double vb = (long double)ngave / ((long double)(all - cnt));
    vb *= (long double)1.0 * all / cnt;
    vb -= (long double)ngave / ((long double)(all - cnt));
    return (long double)va + vb + dist[1][sy][sx];
  }
}

int main(void) {
  scanf("%d%d%*c", &w, &h);
  memset(fie, 0, sizeof(fie));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      char c;
      scanf("%c", &c);
      if (c == '#')
        fie[i][j] = -1;
      if (c == 's')
        sy = i, sx = j;
      if (c == 'g')
        gy = i, gx = j;
      if (c == '*')
        fie[i][j] = 1;
    }
    scanf("%*c");
  }
  bfs(gy, gx);
  bfs();
  if (dist[1][sy][sx] == -1 ||
      (dist[0][sy][sx] <= dist[1][sy][sx] && dist[0][sy][sx] != -1)) {
    printf("%.10f\\n", (double)dist[0][sy][sx]);
    return 0;
  }
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (fie[i][j] == 0 && (i != gy || j != gx)) {
        all++;
        if (dist[0][i][j] != -1 && dist[1][i][j] != -1)
          vec.push_back(PP(dist[0][i][j] - dist[1][i][j], P(i, j)));
        else if (dist[0][i][j] == -1)
          ngave += dist[1][i][j];
        else {
          okave += dist[0][i][j];
          cnt++;
        }
      }
    }
  }
  sort(vec.begin(), vec.end());
  long double res = INF;
  for (int i = 0; i < vec.size(); i++) {
    ngave += dist[1][vec[i].second.first][vec[i].second.second];
  }
  for (int i = 0; i <= vec.size(); i++) {
    if (i == vec.size())
      res = min(res, calc(514514));
    else if (all != cnt || cnt != 0)
      res = min(res, calc(vec[i].first));
    if (i != vec.size()) {
      ngave -= dist[1][vec[i].second.first][vec[i].second.second];
      cnt++;
      okave += dist[0][vec[i].second.first][vec[i].second.second];
    }
  }
  printf("%.10f\\n", (double)res);
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>

#define INF 1e18
using namespace std;
typedef pair<int, int> P;
typedef pair<int, P> PP;
int dx[4] = {0, -1, 0, 1};
int dy[4] = {1, 0, -1, 0};
int fie[510][510];
int dist[2][510][510];
int w, h;
vector<PP> vec;
int sx, sy, gx, gy;
typedef long long ll;

void bfs(int y = -1, int x = -1) {
  queue<P> que;
  int type = 0;
  if (y == -1)
    type = 1;
  memset(dist[type], -1, sizeof(dist[type]));
  if (type == 0) {
    dist[type][y][x] = 0;
    que.push(P(y, x));
  } else {
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (fie[i][j] == 1) {
          dist[type][i][j] = 0;
          que.push(P(i, j));
        }
      }
    }
  }
  while (que.size()) {
    P p = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int nx = p.second + dx[i], ny = p.first + dy[i];
      if (abs(fie[ny][nx]) != 1 && dist[type][ny][nx] == -1) {
        dist[type][ny][nx] = dist[type][p.first][p.second] + 1;
        que.push(P(ny, nx));
      }
    }
  }
}

ll cnt = 0;
ll all = 0;
ll okave = 0;
ll ngave = 0;

long double calc(int v) {
  if ((dist[0][sy][sx] != -1 && dist[0][sy][sx] <= dist[1][sy][sx] + v) ||
      dist[1][sy][sx] == -1)
    return dist[0][sy][sx];
  else {
    if (cnt == 0)
      return INF;
    long double va = (long double)okave / all;
    va *= (double)1.0 * all / cnt;
    long double vb = (long double)ngave / ((long double)(all - cnt));
    vb *= (long double)1.0 * all / cnt;
    vb -= (long double)ngave / ((long double)(all - cnt));
    return (long double)va + vb + dist[1][sy][sx];
  }
}

int main(void) {
  scanf("%d%d%*c", &w, &h);
  memset(fie, 0, sizeof(fie));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      char c;
      scanf("%c", &c);
      if (c == '#')
        fie[i][j] = -1;
      if (c == 's')
        sy = i, sx = j;
      if (c == 'g')
        gy = i, gx = j;
      if (c == '*')
        fie[i][j] = 1;
    }
    scanf("%*c");
  }
  bfs(gy, gx);
  bfs();
  if (dist[1][sy][sx] == -1 ||
      (dist[0][sy][sx] <= dist[1][sy][sx] && dist[0][sy][sx] != -1)) {
    printf("%.10f\\n", (double)dist[0][sy][sx]);
    return 0;
  }
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (fie[i][j] == 0 && (i != gy || j != gx)) {
        all++;
        if (dist[0][i][j] != -1 && dist[1][i][j] != -1)
          vec.push_back(PP(dist[0][i][j] - dist[1][i][j], P(i, j)));
        else if (dist[0][i][j] == -1)
          ngave += dist[1][i][j];
        else {
          okave += dist[0][i][j];
          cnt++;
        }
      }
    }
  }
  if (vec.size() > 0)
    sort(vec.begin(), vec.end());
  long double res = INF;
  for (int i = 0; i < vec.size(); i++) {
    ngave += dist[1][vec[i].second.first][vec[i].second.second];
  }
  for (int i = 0; i <= vec.size(); i++) {
    res = min(res, calc(vec[i].first));
    if (i != vec.size()) {
      ngave -= dist[1][vec[i].second.first][vec[i].second.second];
      cnt++;
      okave += dist[0][vec[i].second.first][vec[i].second.second];
    }
  }
  printf("%.10f\\n", (double)res);
  return 0;
}