Problem p01453 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <cstdio>
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
int main() {
  int W, H, gx, gy, sx, sy, n = 0;
  cin >> W >> H;
  string M[H];
  vector<pair<int, int>> springs;
  for (int i = 0; i < H; ++i) {
    cin >> M[i];
    for (int j = 0; j < W; ++j) {
      if (M[i][j] == 'g') {
        gx = i;
        gy = j;
        M[i][j] = '.';
      } else if (M[i][j] == 's') {
        sx = i;
        sy = j;
        M[i][j] = '.';
        ++n;
      } else if (M[i][j] == '.')
        ++n;
      else if (M[i][j] == '*') {
        springs.push_back(make_pair(i, j));
      }
    }
  }
  long double INF = (1e10), l = 0.0, r = INF, exp_[H][W], exp[H][W];

  int d[] = {1, 0, -1, 0};
  queue<pair<int, int>> que;
  que.push(make_pair(gx, gy));
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      exp_[i][j] = INF;
      exp[i][j] = INF;
    }
  }

  exp_[gx][gy] = 0.0;
  while (!que.empty()) {
    int x = que.front().first, y = que.front().second;
    que.pop();
    for (int k = 0; k < 4; ++k) {
      int x_ = x + d[k], y_ = y + d[(k + 1) % 4];
      if (x_ >= H || x_ < 0 || y_ >= W || y_ < 0)
        continue;
      char c = M[x_][y_];
      if (c == '.' && exp_[x_][y_] > exp_[x][y] + 1) {
        exp_[x_][y_] = exp_[x][y] + 1;
        que.push(make_pair(x_, y_));
      }
    }
  }
  /*
  long double dist_from_spring[H][W];
  for(int i = 0; i < H; ++i){
    for(int j = 0; j < W; ++j){
      dist_from_spring[i][j] = INF;
    }
  }
  */
  vector<vector<long double>> dist_from_spring(H, vector<long double>(W, INF));
  for (int i = 0; i < springs.size(); ++i) {
    queue<pair<int, int>> que2;
    que2.push(make_pair(springs[i].first, springs[i].second));
    dist_from_spring[springs[i].first][springs[i].second] = 0;
    while (!que2.empty()) {
      int x = que2.front().first, y = que2.front().second;
      que2.pop();
      for (int k = 0; k < 4; ++k) {
        int x_ = x + d[k], y_ = y + d[(k + 1) % 4];
        if (x_ >= H || x_ < 0 || y_ >= W || y_ < 0)
          continue;
        char c = M[x_][y_];
        if (c == '.' &&
            (dist_from_spring[x_][y_] > dist_from_spring[x][y] + 1)) {
          que2.push(make_pair(x_, y_));
          dist_from_spring[x_][y_] = dist_from_spring[x][y] + 1;
        }
      }
    }
  }

  for (int t = 0; t < 100; ++t) {
    long double mean = (l + r) / 2.0;
    long double s = 0.0;
    for (int i = 0; i < H; ++i) {
      for (int j = 0; j < W; ++j) {
        if (M[i][j] == '.') {
          exp[i][j] = min(exp_[i][j], dist_from_spring[i][j] + mean);
          s += exp[i][j];
        }
      }
    }

    if (s / n < mean) {
      r = mean;
    } else {
      l = mean;
    }
  }
  printf("%.12Lf\\n", exp[sx][sy]);
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
int main() {
  int W, H, gx, gy, sx, sy, n = 0;
  cin >> W >> H;
  string M[H];
  vector<pair<int, int>> springs;
  for (int i = 0; i < H; ++i) {
    cin >> M[i];
    for (int j = 0; j < W; ++j) {
      if (M[i][j] == 'g') {
        gx = i;
        gy = j;
        M[i][j] = '.';
      } else if (M[i][j] == 's') {
        sx = i;
        sy = j;
        M[i][j] = '.';
        ++n;
      } else if (M[i][j] == '.')
        ++n;
      else if (M[i][j] == '*') {
        springs.push_back(make_pair(i, j));
      }
    }
  }
  long double INF = (1e10), l = 0.0, r = INF, exp_[H][W], exp[H][W];

  int d[] = {1, 0, -1, 0};
  queue<pair<int, int>> que;
  que.push(make_pair(gx, gy));
  for (int i = 0; i < H; ++i)
    for (int j = 0; j < W; ++j)
      exp_[i][j] = INF;

  exp_[gx][gy] = 0.0;
  while (!que.empty()) {
    int x = que.front().first, y = que.front().second;
    que.pop();
    for (int k = 0; k < 4; ++k) {
      int x_ = x + d[k], y_ = y + d[(k + 1) % 4];
      if (x_ > H || x_ < 0 || y_ > W || y_ < 0)
        continue;
      char c = M[x_][y_];
      if (c == '.' && exp_[x_][y_] > exp_[x][y] + 1) {
        exp_[x_][y_] = exp_[x][y] + 1;
        que.push(make_pair(x_, y_));
      }
    }
  }

  for (int t = 0; t < 100; ++t) {
    long double mean = (l + r) / 2.0;

    for (int i = 0; i < H; ++i)
      for (int j = 0; j < W; ++j)
        exp[i][j] = exp_[i][j];

    for (int i = 0; i < springs.size(); ++i) {
      queue<pair<int, int>> que2;
      que2.push(make_pair(springs[i].first, springs[i].second));
      exp[springs[i].first][springs[i].second] = mean;
      while (!que2.empty()) {
        int x = que2.front().first, y = que2.front().second;
        que2.pop();
        for (int k = 0; k < 4; ++k) {
          int x_ = x + d[k], y_ = y + d[(k + 1) % 4];
          if (x_ > H || x_ < 0 || y_ > W || y_ < 0)
            continue;
          char c = M[x_][y_];
          if (c == '.' && (exp[x_][y_] > exp[x][y] + 1)) {
            que2.push(make_pair(x_, y_));
            exp[x_][y_] = exp[x][y] + 1;
          }
        }
      }
    }

    long double s = 0.0;
    for (int i = 0; i < H; ++i) {
      for (int j = 0; j < W; ++j) {
        if (M[i][j] == '.') {
          s += exp[i][j];
        }
      }
    }
    if (s / n < mean) {
      r = mean;
    } else {
      l = mean;
    }
  }
  printf("%.12Lf\\n", exp[sx][sy]);
  return 0;
}