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

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <queue>
#include <string>

#define REP(i, a, n) for (int i = (a); i < (n); ++i)

#define INV (-1)
#define N 102
#define INFTY (1 << 30)
#define PLANE 2
#define MOAT 1

using namespace std;

int n, m;
int map[N][N];
int M[N][N];

bool inline inRange(int t, int min, int max) { return min <= t && t < max; }

void dfs(int i, int j, int now) {
  const int ci[] = {-1, 0, 1, 0};
  const int cj[] = {0, 1, 0, -1};

  if (M[i][j] != now)
    return;

  for (int k = 0; k < sizeof(ci) / sizeof(*ci); ++k) {
    int ti = i + ci[k];
    int tj = j + cj[k];
    if (inRange(ti, 0, m + 2) && inRange(tj, 0, n + 2)) {
      if (map[i][j] == MOAT && map[ti][tj] == PLANE) {
        M[ti][tj] = min(M[ti][tj], now + 1);
        continue;
      }
      if (M[ti][tj] == now) {
        continue;
      }
      M[ti][tj] = now;
      dfs(ti, tj, now);
    }
  }
  return;
}
void ResetMap() {
  REP(i, 0, N) REP(j, 0, N) {
    map[i][j] = PLANE;
    M[i][j] = INFTY;
  }
}
void PrintMap() {
  REP(i, 1, m + 1) {
    REP(j, 1, n + 1) { cout << setw(3) << M[i][j]; }
    cout << endl;
  }
  cout << endl;
}
bool Completed(int *ans) {
  REP(i, 0, m + 2) {
    if (M[i][0] < INFTY) {
      *ans = M[i][0];
      return true;
    }
    if (M[i][n + 1] < INFTY) {
      *ans = M[i][n + 1];
      return true;
    }
  }
  REP(j, 0, n + 2) {
    if (M[0][j] < INFTY) {
      *ans = M[0][j];
      return true;
    }
    if (M[m + 1][j] < INFTY) {
      *ans = M[m + 1][j];
      return true;
    }
  }

  return false;
}

int main() {
  while (true) {
    int now = 0;
    int ans = 1 << 21;
    int si;
    int sj;

    cin >> n >> m;
    if (m == 0 && n == 0)
      break;

    ResetMap();

    REP(i, 1, m + 1) {
      string s;
      cin >> s;
      REP(j, 1, n + 1) {
        if (s[j - 1] == '&') {
          si = i;
          sj = j;
          M[si][sj] = 0;
        } else if (s[j - 1] == '#') {
          map[i][j] = MOAT;
        }
      }
    }

    while (true) {
      REP(i, 1, m + 1) {
        REP(j, 1, n + 1) { dfs(i, j, now); }
      }
      if (Completed(&ans))
        break;
      else {
        ++now;
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <queue>
#include <string>

#define REP(i, a, n) for (int i = (a); i < (n); ++i)

#define INV (-1)
#define N 102
#define INFTY 1 << 30
#define PLANE 2
#define MOAT 1

using namespace std;

struct Node {
  int i, j;
  int w;
  int v;
  bool vis;
};

class GreaterPNode {
public:
  bool operator()(const Node *a, const Node *b) const { return a->w > b->w; }
};

int n, m;
Node map[N][N];

bool inRange(int t, int Min, int Max) { return Min <= t && t < Max; }

int dijkstra(int i, int j, int gi, int gj) {
  const int ci[] = {-1, 0, 1, 0};
  const int cj[] = {0, 1, 0, -1};
  Node *p = &map[i][j];
  priority_queue<Node *, vector<Node *>, GreaterPNode> pq;

  p->w = 0;
  pq.push(p);

  while (!pq.empty()) {
    p = pq.top();
    pq.pop();

    p->vis = false;
    if (p->i == gi && p->j == gj)
      return 1;

    for (int k = 0; k < 4; ++k) {
      int ti = p->i + ci[k], tj = p->j + cj[k];
      if (inRange(ti, 1, m + 1) && inRange(tj, 1, n + 1)) {
        int cost = 0;
        Node *q = &map[ti][tj];

        if (p->v == MOAT && q->v == PLANE) {
          cost = 1;
        }

        if (!q->vis && q->w > p->w + cost) {
          q->w = p->w + cost;
          pq.push(q);
        }
      }
    }
  }
  return -1;
}

void ResetMap(bool bAll) {
  REP(i, 0, N) REP(j, 0, N) {
    map[i][j].i = i;
    map[i][j].j = j;
    if (bAll)
      map[i][j].v = PLANE;
    map[i][j].w = INFTY;
    map[i][j].vis = false;
  }
}

void PrintMap() {
  REP(i, 1, m + 1) {
    REP(j, 1, n + 1) { cout << setw(3) << map[i][j].w; }
    cout << endl;
  }
  cout << endl;
}

int main() {
  while (true) {
    int gi, gj;
    int ans = INFTY;

    cin >> n >> m;
    if (m == 0 && n == 0)
      break;

    ResetMap(true);

    REP(i, 1, m + 1) {
      string s;
      cin >> s;
      REP(j, 1, n + 1) {
        if (s[j - 1] == '&') {
          gi = i;
          gj = j;
        } else if (s[j - 1] == '#') {
          map[i][j].v = MOAT;
        }
      }
    }

    REP(i, 1, m + 1) {
      dijkstra(i, 1, gi, gj);
      ans = min(ans, map[gi][gj].w);
      ResetMap(false);
    }
    REP(i, 1, m + 1) {
      dijkstra(i, n, gi, gj);
      ans = min(ans, map[gi][gj].w);
      ResetMap(false);
    }
    REP(j, 1, n + 1) {
      dijkstra(1, j, gi, gj);
      ans = min(ans, map[gi][gj].w);
      ResetMap(false);
    }
    REP(j, 1, n + 1) {
      dijkstra(m, j, gi, gj);
      ans = min(ans, map[gi][gj].w);
      ResetMap(false);
    }
    cout << ans << endl;
  }
  return 0;
}