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

#include "bits/stdc++.h"
#include <unordered_map>
#pragma warning(disable : 4996)
using namespace std;

vector<vector<int>> fi;

vector<vector<long long int>> spt, got;

struct aa {
  int y;
  int x;
  int time;
};
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

class Compare {
public:
  // keiroが昇順に並ぶ
  bool operator()(const aa &l, const aa &r) { return l.time > r.time; }
};

int main() {
  int W, H;
  cin >> W >> H;
  int sx, sy;
  pair<int, int> gp;
  vector<pair<int, int>> sps;
  fi.resize(H);
  spt.resize(H);
  got.resize(H);
  for (int i = 0; i < H; ++i) {

    string st;
    cin >> st;
    for (int j = 0; j < W; ++j) {
      spt[i].emplace_back(9999999999);
      got[i].emplace_back(9999999999);
      int wh;
      if (st[j] == '.') {
        wh = 0;
      } else if (st[j] == '#') {
        wh = 1;
      } else if (st[j] == '*') {
        wh = 2;
        sps.push_back(make_pair(i, j));
      } else if (st[j] == 's') {
        wh = 0;
        sx = j;
        sy = i;
      } else if (st[j] == 'g') {
        wh = 4;
        gp.first = i;
        gp.second = j;
      } else {
        assert(false);
      }
      fi[i].push_back(wh);
    }
  }
  {
    priority_queue<aa, vector<aa>, Compare> que;
    for (int i = 0; i < sps.size(); ++i) {
      que.push(aa{sps[i].first, sps[i].second, 0});
      spt[sps[i].first][sps[i].second] = 0;
    }

    while (!que.empty()) {
      aa atop(que.top());
      que.pop();
      for (int i = 0; i < 4; ++i) {
        const int nx = atop.x + dx[i];
        const int ny = atop.y + dy[i];
        const int nt = atop.time + 1;
        if (!fi[ny][nx]) {
          if (spt[ny][nx] > nt) {
            spt[ny][nx] = nt;
            que.push(aa{ny, nx, nt});
          }
        }
      }
    }
  }
  {
    priority_queue<aa, vector<aa>, Compare> que;
    que.push(aa{gp.first, gp.second, 0});
    got[gp.first][gp.second] = 0;

    while (!que.empty()) {
      aa atop(que.top());
      que.pop();
      for (int i = 0; i < 4; ++i) {
        const int nx = atop.x + dx[i];
        const int ny = atop.y + dy[i];
        const int nt = atop.time + 1;
        if (!fi[ny][nx]) {
          if (got[ny][nx] > nt) {
            got[ny][nx] = nt;
            que.push(aa{ny, nx, nt});
          }
        }
      }
    }
  }

  __float128 amin = 0;
  __float128 amax = 1e11;
  bool ok = true;
  while (amin + 1e-10 < amax) {
    __float128 amid = (amin + amax) / 2;

    __float128 timesum = 0;
    __float128 placesum = 0;
    for (int y = 0; y < H; ++y) {
      for (int x = 0; x < W; ++x) {
        if (!fi[y][x]) {
          if (got[y][x] == 9999999999 && spt[y][x] == 9999999999) {
            ok = false;
            break;
          }
          placesum++;
          timesum += min(static_cast<__float128>(got[y][x]), spt[y][x] + amid);
        }
      }
    }
    if (amid < timesum / placesum) {
      amin = amid;
    } else {
      amax = amid;
    }
  }
  long double ans;
  if (ok) {
    ans = min(static_cast<__float128>(got[sy][sx]), spt[sy][sx] + amin);

  } else {
    ans = static_cast<long double>(got[sy][sx]);
  }
  cout << fixed << setprecision(22) << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#pragma warning(disable : 4996)
using namespace std;

vector<vector<int>> fi;

vector<vector<long long int>> spt, got;

struct aa {
  int y;
  int x;
  int time;
};
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

class Compare {
public:
  // keiroが昇順に並ぶ
  bool operator()(const aa &l, const aa &r) { return l.time > r.time; }
};

int main() {
  int W, H;
  cin >> W >> H;
  int sx, sy;
  pair<int, int> gp;
  vector<pair<int, int>> sps;
  fi.resize(H);
  spt.resize(H);
  got.resize(H);
  for (int i = 0; i < H; ++i) {

    string st;
    cin >> st;
    for (int j = 0; j < W; ++j) {
      spt[i].emplace_back(9999999999);
      got[i].emplace_back(9999999999);
      int wh;
      if (st[j] == '.') {
        wh = 0;
      } else if (st[j] == '#') {
        wh = 1;
      } else if (st[j] == '*') {
        wh = 2;
        sps.push_back(make_pair(i, j));
      } else if (st[j] == 's') {
        wh = 0;
        sx = j;
        sy = i;
      } else if (st[j] == 'g') {
        wh = 4;
        gp.first = i;
        gp.second = j;
      } else {
        assert(false);
      }
      fi[i].push_back(wh);
    }
  }
  {
    priority_queue<aa, vector<aa>, Compare> que;
    for (int i = 0; i < sps.size(); ++i) {
      que.push(aa{sps[i].first, sps[i].second, 0});
      spt[sps[i].first][sps[i].second] = 0;
    }

    while (!que.empty()) {
      aa atop(que.top());
      que.pop();
      for (int i = 0; i < 4; ++i) {
        const int nx = atop.x + dx[i];
        const int ny = atop.y + dy[i];
        const int nt = atop.time + 1;
        if (!fi[ny][nx]) {
          if (spt[ny][nx] > nt) {
            spt[ny][nx] = nt;
            que.push(aa{ny, nx, nt});
          }
        }
      }
    }
  }
  {
    priority_queue<aa, vector<aa>, Compare> que;
    que.push(aa{gp.first, gp.second, 0});
    got[gp.first][gp.second] = 0;

    while (!que.empty()) {
      aa atop(que.top());
      que.pop();
      for (int i = 0; i < 4; ++i) {
        const int nx = atop.x + dx[i];
        const int ny = atop.y + dy[i];
        const int nt = atop.time + 1;
        if (!fi[ny][nx]) {
          if (got[ny][nx] > nt) {
            got[ny][nx] = nt;
            que.push(aa{ny, nx, nt});
          }
        }
      }
    }
  }

  long double amin = 0;
  long double amax = 1e11;
  bool ok = true;
  while (amin + 1e-10 < amax) {
    long double amid = (amin + amax) / 2;

    long double timesum = 0;
    long double placesum = 0;
    for (int y = 0; y < H; ++y) {
      for (int x = 0; x < W; ++x) {
        if (!fi[y][x]) {
          if (got[y][x] == 9999999999 && spt[y][x] == 9999999999) {
            ok = false;
            break;
          }
          placesum++;
          timesum += min(static_cast<long double>(got[y][x]), spt[y][x] + amid);
        }
      }
    }
    if (amid < timesum / placesum) {
      amin = amid;
    } else {
      amax = amid;
    }
  }
  long double ans;
  if (ok) {
    ans = min(static_cast<long double>(got[sy][sx]), spt[sy][sx] + amin);

  } else {
    ans = static_cast<long double>(got[sy][sx]);
  }
  cout << fixed << setprecision(22) << ans << endl;
  return 0;
}