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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <ctime>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

class CPoint {
public:
  int x, y;

  CPoint() : x(0), y(0){};
  CPoint(int ax, int ay) : x(ax), y(ay){};

  bool operator==(const CPoint &obj);
  bool operator!=(const CPoint &obj);

  CPoint operator+(const CPoint &obj);
};

class CPoint;

const int MAX_H = 1000;
const int MAX_W = 1000;
const ll INF = 1000000000;

char field[MAX_H][MAX_W];
bool used[MAX_H][MAX_W];
ll d[MAX_H][MAX_W];
int H, W, N;

ll getroad(CPoint start, CPoint goal);

int main() {
  cin >> H >> W >> N;
  vector<CPoint> factorys(N + 1);

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> field[i][j];
      if (field[i][j] != 'X' && field[i][j] != '.') {
        if (field[i][j] == 'S')
          factorys[0] = CPoint(i, j);
        else
          factorys[field[i][j] - '0'] = CPoint(i, j);
      }
    }
  }

  ll res = 0;
  for (int i = 0; i < N; i++)
    res += getroad(factorys[i], factorys[i + 1]);

  cout << res << endl;
}

ll getroad(CPoint start, CPoint goal) {
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      d[i][j] = INF;

  queue<CPoint> que;
  que.push(start);
  d[start.x][start.y] = 0;

  while (!que.empty()) {
    CPoint v = que.front();
    que.pop();
    if (v.y + 1 < W && field[v.x][v.y + 1] != 'X' &&
        d[v.x][v.y] + 1 < d[v.x][v.y + 1]) {
      d[v.x][v.y + 1] = d[v.x][v.y] + 1;
      que.push(v + CPoint(0, 1));
    }
    if (v.y - 1 >= 0 && field[v.x][v.y - 1] != 'X' &&
        d[v.x][v.y] + 1 < d[v.x][v.y - 1]) {
      d[v.x][v.y - 1] = d[v.x][v.y] + 1;
      que.push(v + CPoint(0, -1));
    }
    if (v.x + 1 < H && field[v.x + 1][v.y] != 'X' &&
        d[v.x][v.y] + 1 < d[v.x + 1][v.y]) {
      d[v.x + 1][v.y] = d[v.x][v.y] + 1;
      que.push(v + CPoint(1, 0));
    }
    if (v.x - 1 >= 0 && field[v.x - 1][v.y] != 'X' &&
        d[v.x][v.y] + 1 < d[v.x - 1][v.y]) {
      d[v.x - 1][v.y] = d[v.x][v.y] + 1;
      que.push((v + CPoint(-1, 0)));
    }
  }
  return d[goal.x][goal.y];
}

bool CPoint::operator==(const CPoint &obj) {
  return (x == obj.x && y == obj.y);
}

bool CPoint::operator!=(const CPoint &obj) { return !(*this == obj); }

CPoint CPoint::operator+(const CPoint &obj) {
  CPoint tmp;
  tmp.x = x + obj.x;
  tmp.y = y + obj.y;
  return tmp;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

class CPoint {
public:
  int x, y;

  CPoint() : x(0), y(0){};
  CPoint(int ax, int ay) : x(ax), y(ay){};

  bool operator==(const CPoint &obj);
  bool operator!=(const CPoint &obj);
};

class CPoint;

const int MAX_H = 1000;
const int MAX_W = 1000;
const ll INF = 1000000000;

char field[MAX_H][MAX_W];
bool used[MAX_H][MAX_W];
ll d[MAX_H][MAX_W];
int H, W, N;

ll getroad(CPoint start, CPoint goal);

int main() {
  cin >> H >> W >> N;
  vector<CPoint> factorys(N + 1);

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> field[i][j];
      if (field[i][j] != 'X' && field[i][j] != '.') {
        if (field[i][j] == 'S')
          factorys[0] = CPoint(i, j);
        else
          factorys[field[i][j] - '0'] = CPoint(i, j);
      }
    }
  }

  ll res = 0;
  for (int i = 0; i < N; i++)
    res += getroad(factorys[i], factorys[i + 1]);

  cout << res << endl;

  cin.sync();
  cin.get();
}

ll getroad(CPoint start, CPoint goal) {
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      used[i][j] = false;
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      d[i][j] = INF;

  d[start.x][start.y] = 0;

  while (true) {

    CPoint v(-1, -1);
    for (int i = 0; i < H; i++)
      for (int j = 0; j < W; j++)
        if (!used[i][j] && field[i][j] != 'X' &&
            (v == CPoint(-1, -1) || d[i][j] < d[v.x][v.y]))
          v = CPoint(i, j);

    if (v == CPoint(-1, -1))
      break;

    used[v.x][v.y] = true;

    if (v.y + 1 < W && field[v.x][v.y + 1] != 'X')
      d[v.x][v.y + 1] = min(d[v.x][v.y + 1], d[v.x][v.y] + 1);
    if (v.y - 1 >= 0 && field[v.x][v.y - 1] != 'X')
      d[v.x][v.y - 1] = min(d[v.x][v.y - 1], d[v.x][v.y] + 1);
    if (v.x + 1 < H && field[v.x + 1][v.y] != 'X')
      d[v.x + 1][v.y] = min(d[v.x + 1][v.y], d[v.x][v.y] + 1);
    if (v.x - 1 >= 0 && field[v.x - 1][v.y] != 'X')
      d[v.x - 1][v.y] = min(d[v.x - 1][v.y], d[v.x][v.y] + 1);
  }

  return d[goal.x][goal.y];
}

bool CPoint::operator==(const CPoint &obj) {
  return (x == obj.x && y == obj.y);
}

bool CPoint::operator!=(const CPoint &obj) { return !(*this == obj); }