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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for ((i) = 0; (i) < (int)(n); ++(i))
#define foreach(c, itr)                                                        \\
  for (__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); itr++)
typedef long long ll;
typedef pair<ll, int> P;

struct Point {
  int x, y, id;
  Point() {}
  Point(int a, int b, int c) : x(a), y(b), id(c) {}
};

struct Edge {
  int to, cost;
  Edge(int a, int b) : to(a), cost(b) {}
};

int w, h, max_num;
vector<Point> V[2500];
vector<Edge> es[2500];
Point s, g;

const int inf = 1 << 28;
ll dp[2500];

int dijkstra(int s, int g) {
  priority_queue<P, vector<P>, greater<P>> q;
  fill(dp, dp + 2500, inf);
  dp[s] = 0;
  q.push(P(0, s));

  while (!q.empty()) {
    P p = q.top();
    q.pop();
    int v = p.second, i;
    if (dp[v] < p.first)
      continue;
    // cout << v << "|" << dp[v] << endl;
    rep(i, es[v].size()) {
      Edge te = es[v][i];
      if (dp[te.to] > dp[v] + te.cost) {
        dp[te.to] = dp[v] + te.cost;
        q.push(P(dp[te.to], te.to));
      }
    }
  }

  return dp[g];
}

void solve() {
  int i, j, k, id = 1;
  int s_id = 0, g_id;
  max_num = 0;
  string in;

  rep(i, h) rep(j, w) {
    cin >> in;
    if (in == ".")
      continue;
    if (in == "S") {
      s.x = j, s.y = i;
      continue;
    }
    if (in == "G") {
      g.x = j, g.y = i;
      continue;
    }
    int num = atoi(in.c_str());
    max_num = max(max_num, num);
    V[num].push_back(Point(j, i, id));
    id++;
  }
  if (max_num != 0) {
    g_id = id;
    // id of S is 0, id of G is @id.
    // connect S & 1
    rep(i, V[1].size()) {
      int dist = abs(s.x - V[1][i].x) + abs(s.y - V[1][i].y);
      es[0].push_back(Edge(V[1][i].id, dist));
    }
    // connect
    for (i = 1; i < max_num; i++) {
      rep(j, V[i].size()) rep(k, V[i + 1].size()) {
        int dist =
            abs(V[i][j].x - V[i + 1][k].x) + abs(V[i][j].y - V[i + 1][k].y);
        int a_id = V[i][j].id, b_id = V[i + 1][k].id;
        es[a_id].push_back(Edge(b_id, dist));
      }
    }
    // connect max_num & G
    rep(i, V[max_num].size()) {
      int dist = abs(g.x - V[max_num][i].x) + abs(g.y - V[max_num][i].y);
      int t_id = V[max_num][i].id;
      es[t_id].push_back(Edge(g_id, dist));
    }
  } else {
    cout << abs(s.x - g.x) + abs(s.y - g.y) << endl;
    return;
  }

  // dijkstra
  cout << dijkstra(s_id, g_id) << endl;

  // clear
  rep(i, max_num + 1) V[i].clear();
  rep(i, g_id + 1) es[i].clear();
}

int main() {
  while (cin >> w >> h, w | h) {
    solve();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for ((i) = 0; (i) < (int)(n); ++(i))
#define foreach(c, itr)                                                        \\
  for (__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); itr++)

struct Point {
  int x, y;
  Point() {}
  Point(int a, int b) : x(a), y(b) {}
};

int w, h, max_num, ans;
vector<Point> V[2500];
Point s, g;

void dfs(int cur, int x, int y, int cost) {
  if (cost > ans)
    return;
  int i;
  if (cur == max_num) {
    int distance = abs(x - g.x) + abs(y - g.y);
    ans = min(ans, cost + distance);
    return;
  }
  rep(i, V[cur].size()) {
    int distance = abs(x - V[cur][i].x) + abs(y - V[cur][i].y);
    dfs(cur + 1, V[cur][i].x, V[cur][i].y, cost + distance);
  }
}

void solve() {
  int i, j;
  max_num = 0;
  ans = 1 << 28;
  string in;
  rep(i, h) rep(j, w) {
    cin >> in;
    if (in == ".")
      continue;
    if (in == "S") {
      s.x = j, s.y = i;
      continue;
    }
    if (in == "G") {
      g.x = j, g.y = i;
      continue;
    }
    int num = atoi(in.c_str());
    max_num = max(max_num, num);
    V[num].push_back(Point(j, i));
  }
  /*
  for (i = 1; i <= max_num; i++) {
    cout << i << "|";
    rep (j,V[i].size()) {
      cout << "(" << V[i][j].x << ",";
      cout << V[i][j].y << ")";
    }
    cout << endl;
  }*/
  max_num++;
  dfs(1, s.x, s.y, 0);
  rep(i, max_num - 1) V[i].clear();
  cout << ans << endl;
}

int main() {
  while (cin >> w >> h, w | h) {
    solve();
  }
  return 0;
}