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

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>

using namespace std;

#define dump(n) cout << "# " << #n << "=" << (n) << endl
#define debug(n)                                                               \\
  cout << __FILE__ << "," << __LINE__ << ": #" << #n << "=" << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define rep(i, n) repi(i, 0, n)
#define iter(c) __typeof((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); i++)
#define allof(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;

struct Edge {
  int src, dst, weight;
  Edge() {}
  Edge(int src, int dst, int weight) : src(src), dst(dst), weight(weight) {}
};

bool operator<(const Edge &lhs, const Edge &rhs) {
  return lhs.weight < rhs.weight;
}

bool operator>(const Edge &lhs, const Edge &rhs) {
  return lhs.weight > rhs.weight;
}

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

void Dijkstra(const Graph &g, int begin, vi &cost, vi &prev) {
  int size = g.size();
  cost.assign(size, INFTY);
  prev.assign(size, -1);

  priority_queue<Edge, vector<Edge>, greater<Edge>> pq;
  pq.push(Edge(-1, begin, 0));
  cost[begin] = 0;
  while (!pq.empty()) {
    Edge e = pq.top();
    pq.pop();
    if (prev[e.dst] != -1)
      continue;
    prev[e.dst] = e.src;
    rep(i, g[e.dst].size()) {
      Edge cand = g[e.dst][i]; // candidate
      if (cost[cand.dst] > e.weight + cand.weight) {
        cost[cand.dst] = e.weight + cand.weight;
        pq.push(Edge(cand.src, cand.dst, e.weight + cand.weight));
      }
    }
  }
}

int main() {
  for (int w, h; cin >> w >> h, w | h;) {
    vs field(h + 2);
    field[0] = field[h + 1] = string(w + 2, '.');
    rep(i, h) {
      cin >> field[i + 1];
      field[i + 1] = '.' + field[i + 1] + '.';
    }
    h = field.size();
    w = field[0].size();
    Graph g(h * w);
    rep(i, h) rep(j, w) {
      int di[] = {-1, 1, 0, 0};
      int dj[] = {0, 0, -1, 1};
      rep(k, 4) {
        int ni = i + di[k], nj = j + dj[k];
        if (ni < 0 || h <= ni || nj < 0 || w <= nj)
          continue;
        g[i * w + j].push_back(
            Edge(i * w + j, ni * w + nj,
                 field[i][j] == '#' && field[ni][nj] != '#'));
      }
    }
    vi cost, prev;
    Dijkstra(g, 0, cost, prev);
    rep(i, h) rep(j, w) if (field[i][j] == '&') cout << cost[i * w + j] << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>

using namespace std;

#define dump(n) cout << "# " << #n << "=" << (n) << endl
#define debug(n)                                                               \\
  cout << __FILE__ << "," << __LINE__ << ": #" << #n << "=" << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define rep(i, n) repi(i, 0, n)
#define iter(c) __typeof((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); i++)
#define allof(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;

void solve(vs &field, int i, int j, vvi &cost) {
  int h = field.size(), w = field[0].size();

  int di[] = {-1, 1, 0, 0};
  int dj[] = {0, 0, -1, 1};
  rep(k, 4) {
    int ni = i + di[k], nj = j + dj[k];
    if (ni < 0 || h <= ni || nj < 0 || w <= nj)
      continue;
    if (field[ni][nj] == field[i][j] && cost[ni][nj] > cost[i][j]) {
      cost[ni][nj] = cost[i][j];
      solve(field, ni, nj, cost);
    }
  }
  rep(k, 4) {
    int ni = i + di[k], nj = j + dj[k];
    if (ni < 0 || h <= ni || nj < 0 || w <= nj)
      continue;
    if (field[i][j] == '.' && field[ni][nj] == '#' &&
        cost[ni][nj] > cost[i][j]) {
      cost[ni][nj] = cost[i][j];
      solve(field, ni, nj, cost);
    }
  }
  rep(k, 4) {
    int ni = i + di[k], nj = j + dj[k];
    if (ni < 0 || h <= ni || nj < 0 || w <= nj)
      continue;
    if (field[i][j] == '#' && field[ni][nj] == '.' &&
        cost[ni][nj] > cost[i][j]) {
      cost[ni][nj] = cost[i][j] + 1;
      solve(field, ni, nj, cost);
    }
  }
}

int main() {
  for (int w, h; cin >> w >> h, w | h;) {
    vs field(h + 2);
    field[0] = field[h + 1] = string(w + 2, '.');
    rep(i, h) {
      cin >> field[i + 1];
      field[i + 1] = '.' + field[i + 1] + '.';
    }
    pii p;
    rep(i, field.size()) rep(j, field[0].size()) if (field[i][j] == '&') {
      p = mp(i, j);
      field[i][j] = '.';
    }
    vvi cost(field.size(), vi(field[0].size(), 1 << 29));
    cost[0][0] = 0;
    solve(field, 0, 0, cost);
    cout << cost[p.first][p.second] << endl;
  }

  return 0;
}