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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define INF (1 << 25)
int W, H;
char fie[502][502];
int bfs[502][502];
int sps[502][502];
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
struct P {
  int x, y, c;
  P(int x, int y, int c) : x(x), y(y), c(c) {}
};
vector<P> p;
vector<P> s;
void BFS(int x, int y) {
  queue<P> q;
  q.push(P(x, y, 0));
  bfs[x][y] = 0;
  while (!q.empty()) {
    P p = q.front();
    q.pop();
    x = p.x;
    y = p.y;
    int c = p.c;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      if (nx < 0 || ny < 0 || nx >= W || ny >= H)
        continue;
      if (fie[nx][ny] == '#' || fie[nx][ny] == '*')
        continue;
      if (bfs[nx][ny] <= c + 1)
        continue;
      bfs[nx][ny] = c + 1;
      q.push(P(nx, ny, c + 1));
    }
  }
  for (int i = 0; i < (int)p.size(); i++)
    if (bfs[p[i].x][p[i].y] != INF)
      p[i].c = bfs[p[i].x][p[i].y];
}

void BFS2(int x, int y) {
  queue<P> q;
  q.push(P(x, y, 0));
  sps[x][y] = 0;
  while (!q.empty()) {
    P p = q.front();
    q.pop();
    x = p.x;
    y = p.y;
    int c = p.c;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      if (nx < 0 || ny < 0 || nx >= W || ny >= H)
        continue;
      if (fie[nx][ny] == '#' || fie[nx][ny] == '*')
        continue;
      if (sps[nx][ny] <= c + 1)
        continue;
      sps[nx][ny] = c + 1;
      q.push(P(nx, ny, c + 1));
    }
  }
}
double gosaume() {
  double ret = 0.0f;
  for (int i = 0; i < (int)p.size(); i++)
    ret += (double)p[i].c;
  ret /= (double)p.size();

  return ret;
}
/*
double dp[501][501];
double dpg[50];
int used[501][501];
int useg[50];
double max_d=0.0f;
double solve(int x,int y,int jc){
  if(jc>=48){
    //    used[x][y]=1;
    if(bfs[x][y]==-1) return dp[x][y]=(double)INF;
    return dp[x][y]=(double)bfs[x][y];
  }
  if(jc<10 && used[x][y]) return dp[x][y];
  double ret = 0.0f;
  if(sps[x][y]==-1 || sps[x][y]>=bfs[x][y] || max_d >= bfs[x][y]) return
dp[x][y]=(double)bfs[x][y]; for(int i=0;i<(int)p.size();i++){ ret +=
(solve(p[i].x,p[i].y,jc+1)+(double)sps[x][y]);
  }
  ret = min((double)(bfs[x][y]>0?bfs[x][y]:INF),ret/(double)p.size());
  //  printf("st :: %d %d %d ,  %lf %lf\\n",x,y,jc,ret,(double)bfs[x][y]);
  used[x][y]=1;
  return dp[x][y]=ret;
  }*/
double dp[2][250000];
double solve() {
  double max_d = 0.0f;
  int co = 0;
  for (int i = 0; i < (int)p.size(); i++) {
    if (p[i].c != INF) {
      max_d += (double)p[i].c;
      co++;
    }
  }
  max_d /= (double)co;

  //  printf("%lf\\n",max_d);

  for (int id = 0; id < (int)p.size(); id++)
    dp[0][id] = min((double)bfs[p[id].x][p[id].y], max_d);

  for (int i = 50; i > 1; i--) {
    int now = i & 1;
    int next = (now + 1) & 1;

    max_d = 0.0f;
    for (int id = 0; id < (int)p.size(); id++) {
      // printf("before::dp[%d][%d] = %lf\\n",i,id,dp[now][id]);
      max_d += dp[now][id];
      dp[next][id] = 0.0f;
    }

    //    printf("%lf\\n",max_d);

    for (int id = 0; id < (int)p.size(); id++) {
      int x = p[id].x, y = p[id].y;
      double tmp_max = max_d + (double)p.size() * (double)sps[x][y];
      tmp_max /= (double)p.size();
      //      printf("dp[%d][%d] => %lf  VS  %d\\n",i,id,tmp_max,bfs[x][y]);
      if (sps[x][y] == INF) {
        dp[next][id] += (double)bfs[x][y];
      } else if (bfs[x][y] == INF) {
        dp[next][id] += tmp_max;
      } else {
        dp[next][id] += min((double)bfs[x][y], tmp_max);
      }
      //      printf("after::dp[%d][%d] => %lf\\n",i-1,id,dp[next][id]);
    }
  }
}
int main() {
  int gx, gy;
  int sx, sy;
  int ID;
  cin >> W >> H;
  for (int i = 0; i < 501; i++) {
    for (int j = 0; j < 501; j++) {
      bfs[j][i] = INF;
      sps[j][i] = INF;
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> fie[j][i];
      if (fie[j][i] == '.' || fie[j][i] == 's')
        p.push_back(P(j, i, INF));
      if (fie[j][i] == 's') {
        sx = j;
        sy = i;
        ID = p.size() - 1;
      }
      if (fie[j][i] == 'g') {
        gx = j;
        gy = i;
      }
      if (fie[j][i] == '*')
        s.push_back(P(j, i, 0));
    }
  }
  BFS(gx, gy);
  for (int i = 0; i < (int)s.size(); i++)
    BFS2(s[i].x, s[i].y);
  solve();
  printf("%.12lf\\n", dp[0][ID]);
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define INF (1 << 25)
int W, H;
char fie[502][502];
int bfs[502][502];
int sps[502][502];
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
struct P {
  int x, y, c;
  P(int x, int y, int c) : x(x), y(y), c(c) {}
};
vector<P> p;
vector<P> s;
void BFS(int x, int y) {
  queue<P> q;
  q.push(P(x, y, 0));
  bfs[x][y] = 0;
  while (!q.empty()) {
    P p = q.front();
    q.pop();
    x = p.x;
    y = p.y;
    int c = p.c;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      if (nx < 0 || ny < 0 || nx >= W || ny >= H)
        continue;
      if (fie[nx][ny] == '#' || fie[nx][ny] == '*')
        continue;
      if (bfs[nx][ny] != -1)
        continue;
      bfs[nx][ny] = c + 1;
      q.push(P(nx, ny, c + 1));
    }
  }
  for (int i = 0; i < (int)p.size(); i++)
    if (bfs[p[i].x][p[i].y] != -1)
      p[i].c = bfs[p[i].x][p[i].y];
}

void BFS2(int x, int y) {
  queue<P> q;
  q.push(P(x, y, 0));
  sps[x][y] = 0;
  while (!q.empty()) {
    P p = q.front();
    q.pop();
    x = p.x;
    y = p.y;
    int c = p.c;
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      if (nx < 0 || ny < 0 || nx >= W || ny >= H)
        continue;
      if (fie[nx][ny] == '#' || fie[nx][ny] == '*')
        continue;
      if (sps[nx][ny] <= c + 1 && sps[nx][ny] != -1)
        continue;
      sps[nx][ny] = c + 1;
      q.push(P(nx, ny, c + 1));
    }
  }
}
double dp[501][501][50];
int used[501][501][50];
double solve(int x, int y, int jc) {
  if (jc >= 45) {
    used[x][y][jc] = 1;
    if (bfs[x][y] == -1)
      return dp[x][y][jc] = (double)INF;
    return dp[x][y][jc] = (double)bfs[x][y];
  }
  if (used[x][y][jc])
    return dp[x][y][jc];
  double ret = 0.0f;
  if (sps[x][y] == -1)
    return dp[x][y][jc] = (double)bfs[x][y];
  for (int i = 0; i < (int)p.size(); i++) {
    ret +=
        (solve(p[i].x, p[i].y, jc + 1) + (double)sps[x][y]) / (double)p.size();
  }
  ret = min((double)(bfs[x][y] > 0 ? bfs[x][y] : INF), ret);
  //  printf("st :: %d %d %d ,  %lf %lf\\n",x,y,jc,ret,(double)bfs[x][y]);
  used[x][y][jc] = 1;
  return dp[x][y][jc] = ret;
}

int main() {
  int gx, gy;
  int sx, sy;
  cin >> W >> H;
  memset(bfs, -1, sizeof(bfs));
  memset(sps, -1, sizeof(sps));
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> fie[j][i];
      if (fie[j][i] == '.' || fie[j][i] == 's')
        p.push_back(P(j, i, INF));
      if (fie[j][i] == 's') {
        sx = j;
        sy = i;
      }
      if (fie[j][i] == 'g') {
        gx = j;
        gy = i;
      }
      if (fie[j][i] == '*')
        s.push_back(P(j, i, 0));
    }
  }
  BFS(gx, gy);
  for (int i = 0; i < (int)s.size(); i++)
    BFS2(s[i].x, s[i].y);
  printf("%.12lf\\n", solve(sx, sy, 0));
}