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

#include <algorithm>
#include <iostream>
#include <mutex>
#include <queue>
#include <vector>
using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef pair<int, int> P;

struct position {
  int i, j;

  position(int i, int j) : i(i), j(j) {}
};

struct edge {
  int to, cost;

  edge(int to, int cost) : to(to), cost(cost){};
};

const int MAX_V = 3600;
const int INF = 9999999;

int dxl[] = {1, 1, 1, 1, 1, 2, 2, 2, 3}, dyl[] = {-2, -1, 0, 1, 2, -1, 0, 1, 0};
int dxr[] = {-1, -1, -1, -1, -1, -2, -2, -2, -3},
    dyr[] = {-2, -1, 0, 1, 2, -1, 0, 1, 0};

int d[MAX_V];
int V;
vector<edge> G[MAX_V];

int h, w;

bool in(int i, int j) { return 0 <= i && i < h && 0 <= j && j < w; }

int toV(int i, int j, int foot) { return 2 * (i * w + j) + foot; }

void calc(int s) {
  priority_queue<P, vector<P>, greater<P>> que;
  fill(d, d + V, INF);
  d[s] = 0;
  que.push(P(0, s));

  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first)
      continue;
    for (auto &&e : G[v]) {
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

int main() {
  while (cin >> w >> h, w != 0 || h != 0) {
    auto s = vvc(h, vc(w, 0));
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        cin >> s[i][j];

    V = w * h * 2;

    auto start = vector<position>();
    auto goal = vector<position>();
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        if (s[i][j] == 'S')
          start.push_back(position(i, j));
        else if (s[i][j] == 'T')
          goal.push_back(position(i, j));
      }

    for (int i = 0; i < MAX_V; i++)
      G[i].clear();

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        // left foot
        for (int k = 0; k < 9; k++) {
          int ni = i + dyl[k], nj = j + dxl[k];
          if (!in(ni, nj))
            continue;
          if ('1' <= s[ni][nj] && s[ni][nj] <= '9')
            G[toV(i, j, 0)].push_back(edge(toV(ni, nj, 1), s[ni][nj] - '0'));
          else if (s[ni][nj] == 'S' || s[ni][nj] == 'T')
            G[toV(i, j, 0)].push_back(edge(toV(ni, nj, 1), 0));
        }
        // right foot
        for (int k = 0; k < 9; k++) {
          int ni = i + dyr[k], nj = j + dxr[k];
          if (!in(ni, nj))
            continue;
          if ('1' <= s[ni][nj] && s[ni][nj] <= '9')
            G[toV(i, j, 1)].push_back(edge(toV(ni, nj, 0), s[ni][nj] - '0'));
          else if (s[ni][nj] == 'S' || s[ni][nj] == 'T')
            G[toV(i, j, 1)].push_back(edge(toV(ni, nj, 0), 0));
        }
      }
    }

    int ans = INF;
    for (auto &&sp : start) {
      calc(toV(sp.i, sp.j, 0));
      for (auto &&gp : goal) {
        ans = min(ans, d[toV(gp.i, gp.j, 0)]);
        ans = min(ans, d[toV(gp.i, gp.j, 1)]);
      }
      calc(toV(sp.i, sp.j, 1));
      for (auto &&gp : goal) {
        ans = min(ans, d[toV(gp.i, gp.j, 0)]);
        ans = min(ans, d[toV(gp.i, gp.j, 1)]);
      }
    }

    if (ans == INF)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<char> vc;
typedef vector<vc> vvc;

struct position {
  int i, j;

  position(int i, int j) : i(i), j(j) {}
};

const int MAX_V = 3600;
const int INF = 9999999;

int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
int dxl[] = {1, 1, 1, 1, 1, 2, 2, 2, 3}, dyl[] = {-2, -1, 0, 1, 2, -1, 0, 1, 0};
int dxr[] = {-1, -1, -1, -1, -1, -2, -2, -2, -3},
    dyr[] = {-2, -1, 0, 1, 2, -1, 0, 1, 0};

int cost[MAX_V][MAX_V];
int d[MAX_V];
bool used[MAX_V];
int V;

int h, w;

bool in(int i, int j) { return 0 <= i && i < h && 0 <= j && j < w; }

int toV(int i, int j, int foot) { return 2 * (i * w + j) + foot; }

void calc(int s) {
  fill(d, d + V, INF);
  fill(used, used + V, false);
  d[s] = 0;

  while (true) {
    int v = -1;
    for (int u = 0; u < V; u++) {
      if (!used[u] && (v == -1 || d[u] < d[v]))
        v = u;
    }

    if (v == -1)
      break;
    used[v] = true;
    for (int u = 0; u < V; u++) {
      d[u] = min(d[u], d[v] + cost[v][u]);
    }
  }
}

int main() {
  while (cin >> w >> h, w != 0 || h != 0) {
    auto s = vvc(h, vc(w, 0));
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        cin >> s[i][j];

    for (int i = 0; i < MAX_V; i++)
      for (int j = 0; j < MAX_V; j++)
        cost[i][j] = INF;

    V = w * h * 2;

    auto start = vector<position>();
    auto goal = vector<position>();
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        if (s[i][j] == 'S')
          start.push_back(position(i, j));
        else if (s[i][j] == 'T')
          goal.push_back(position(i, j));
      }

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cost[toV(i, j, 0)][toV(i, j, 0)] = 0;
        cost[toV(i, j, 1)][toV(i, j, 1)] = 0;

        // left foot
        for (int k = 0; k < 9; k++) {
          int ni = i + dyl[k], nj = j + dxl[k];
          if (!in(ni, nj))
            continue;
          if ('1' <= s[ni][nj] && s[ni][nj] <= '9')
            cost[toV(i, j, 0)][toV(ni, nj, 1)] = s[ni][nj] - '0';
          else if (s[ni][nj] == 'S' || s[ni][nj] == 'T')
            cost[toV(i, j, 0)][toV(ni, nj, 1)] = 0;
        }

        // right foot
        for (int k = 0; k < 9; k++) {
          int ni = i + dyr[k], nj = j + dxr[k];
          if (!in(ni, nj))
            continue;
          if ('1' <= s[ni][nj] && s[ni][nj] <= '9')
            cost[toV(i, j, 1)][toV(ni, nj, 0)] = s[ni][nj] - '0';
          else if (s[ni][nj] == 'S' || s[ni][nj] == 'T')
            cost[toV(i, j, 1)][toV(ni, nj, 0)] = 0;
        }
      }
    }

    int ans = INF;
    for (auto &&sp : start) {
      calc(toV(sp.i, sp.j, 0));
      for (auto &&gp : goal) {
        ans = min(ans, d[toV(gp.i, gp.j, 0)]);
        ans = min(ans, d[toV(gp.i, gp.j, 1)]);
      }
      calc(toV(sp.i, sp.j, 1));
      for (auto &&gp : goal) {
        ans = min(ans, d[toV(gp.i, gp.j, 0)]);
        ans = min(ans, d[toV(gp.i, gp.j, 1)]);
      }
    }

    if (ans == INF)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}