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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<ll, P> PP;
int w, h, sx, sy, gx, gy, num;
string s[500];
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
ll dg[500][500], db[500][500], inf = 1e18;
void gbfs(int gx, int gy) {
  rep(i, h) rep(j, w) dg[i][j] = inf;
  dg[gx][gy] = 0;
  queue<PP> que;
  que.push(PP(dg[gx][gy], P(gx, gy)));
  while (!que.empty()) {
    PP pp = que.front();
    que.pop();
    P p = pp.second;
    rep(i, 4) {
      int nx = p.fs + dx[i], ny = p.sc + dy[i];
      if (s[nx][ny] != '#' && s[nx][ny] != '*' && dg[nx][ny] == inf) {
        dg[nx][ny] = pp.fs + 1;
        que.push(PP(dg[nx][ny], P(nx, ny)));
      }
    }
  }
}
void bbfs() {
  queue<PP> que;
  rep(i, h) rep(j, w) {
    if (s[i][j] != '*')
      db[i][j] = inf;
    else
      que.push(PP(0, P(i, j)));
  }
  while (!que.empty()) {
    PP pp = que.front();
    que.pop();
    P p = pp.second;
    rep(i, 4) {
      int nx = p.fs + dx[i], ny = p.sc + dy[i];
      if (s[nx][ny] != '#' && s[nx][ny] != '*' && db[nx][ny] == inf) {
        db[nx][ny] = pp.fs + 1;
        que.push(PP(db[nx][ny], P(nx, ny)));
      }
    }
  }
}
bool check(long double x) {
  long double sum = 0;
  rep(i, h) rep(j, w) if (s[i][j] != '#' && s[i][j] != '*') sum +=
      min(x + db[i][j], (long double)dg[i][j]);
  return sum / num < x;
}
int main() {
  cin >> w >> h;
  rep(i, h) cin >> s[i];
  rep(i, h) rep(j, w) {
    if (s[i][j] == 's')
      sx = i, sy = j, num++;
    if (s[i][j] == 'g')
      gx = i, gy = j;
    if (s[i][j] == '.')
      num++;
  }
  gbfs(gx, gy);
  bbfs();
  bool flag = false;
  rep(i, h) rep(j, w) {
    if (s[i][j] != '#' && dg[i][j] == inf && db[i][j] == inf)
      flag = true;
  }
  if (flag) {
    printf("%lld\\n", dg[sx][sy]);
    return 0;
  }
  long double ub = 500.0 * 500 * 500 * 500, lb = 0;
  int cnt = 0;
  while (cnt < 100) {
    //		cout<<ub<<" "<<lb<<endl;
    cnt++;
    long double mid = (ub + lb) / 2;
    if (check(mid))
      ub = mid;
    else
      lb = mid;
  }
  printf("%.12f\\n", (double)min(ub + db[sx][sy], (long double)dg[sx][sy]));
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl;
typedef pair<int, int> P;
typedef pair<int, P> PP;
int w, h, sx, sy, gx, gy, num, inf = 1e8;
string s[500];
int dg[500][500], db[500][500], dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
void gbfs(int gx, int gy) {
  rep(i, h) rep(j, w) dg[i][j] = inf;
  dg[gx][gy] = 0;
  queue<PP> que;
  que.push(PP(dg[gx][gy], P(gx, gy)));
  while (!que.empty()) {
    PP pp = que.front();
    que.pop();
    P p = pp.second;
    rep(i, 4) {
      int nx = p.fs + dx[i], ny = p.sc + dy[i];
      if (s[nx][ny] != '#' && s[nx][ny] != '*' && dg[nx][ny] == inf) {
        dg[nx][ny] = pp.fs + 1;
        que.push(PP(dg[nx][ny], P(nx, ny)));
      }
    }
  }
}
void bbfs() {
  queue<PP> que;
  rep(i, h) rep(j, w) {
    if (s[i][j] != '*')
      db[i][j] = inf;
    else
      que.push(PP(0, P(i, j)));
  }
  while (!que.empty()) {
    PP pp = que.front();
    que.pop();
    P p = pp.second;
    rep(i, 4) {
      int nx = p.fs + dx[i], ny = p.sc + dy[i];
      if (s[nx][ny] != '#' && s[nx][ny] != '*' && db[nx][ny] == inf) {
        db[nx][ny] = pp.fs + 1;
        que.push(PP(db[nx][ny], P(nx, ny)));
      }
    }
  }
}
bool check(long double x) {
  long double sum = 0;
  rep(i, h) rep(j, w) if (s[i][j] != '#' && s[i][j] != '*') sum +=
      min(x + db[i][j], (long double)dg[i][j]);
  return sum / num < x;
}
int main() {
  cin >> w >> h;
  rep(i, h) cin >> s[i];
  rep(i, h) rep(j, w) {
    if (s[i][j] == 's')
      sx = i, sy = j, num++;
    if (s[i][j] == 'g')
      gx = i, gy = j;
    if (s[i][j] == '.')
      num++;
  }
  gbfs(gx, gy);
  bbfs();
  /*bool flag=false;
  rep(i,h) rep(j,w){
          if(s[i][j]!='#'&&dg[i][j]==inf&&db[i][j]==inf) flag=true;
  }
  if(flag){
          printf("%d\\n",dg[sx][sy]);
          return 0;
  }*/
  long double ub = 1e100, lb = 0;
  while (ub - lb > 1e-12) {
    //		cout<<ub<<" "<<lb<<endl;
    long double mid = (ub + lb) / 2;
    if (check(mid))
      ub = mid;
    else
      lb = mid;
  }
  printf("%.12f\\n", (double)min(ub + db[sx][sy], (long double)dg[sx][sy]));
}