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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#define LL long long

const int MAXN = 57;
const int MAXM = 10007;
const long long LLINF = 9000000000000000000;
const int INF = 2000000000; // careful because of floyed and so on
const int MOD = 1000000007;
double eps = 0.00000001;

using namespace std;

struct Point {
  int x, y;
};

const int u[4] = {0, 0, 1, -1};
const int w[4] = {1, -1, 0, 0};

int n, m, q;
char s[MAXN][MAXN];
vector<int> t[MAXN][MAXN];
int on[MAXN][MAXN];
int off[MAXN][MAXN];
int cost[MAXN][MAXN];
int x[MAXM], y[MAXM];
bool vis[MAXN][MAXN];
int d[MAXN][MAXN];

void work(int bx, int by, int ex, int ey) {
  queue<Point> Q;
  memset(vis, 0, sizeof(vis));
  Q.push((Point){bx, by});
  d[bx][by] = t[bx][by][t[bx][by].size() - 1];
  vis[bx][by] = 1;
  while (!Q.empty()) {
    Point now = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int x = now.x + u[i];
      int y = now.y + w[i];
      if (x <= 0 || y <= 0 || x > n || y > m || s[x][y] == '#' || vis[x][y])
        continue;
      vis[x][y] = 1;
      d[x][y] = d[now.x][now.y] + 1;
      Q.push((Point){x, y});
    }
  }
  Q.push((Point){ex, ey});
  while (!Q.empty()) {
    Point now = Q.front();
    if (now.x == bx && now.y == by)
      break;
    t[now.x][now.y].push_back(d[now.x][now.y]);
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int x = now.x + u[i];
      int y = now.y + w[i];
      if (x <= 0 || y <= 0 || x > n || y > m || s[x][y] == '#' ||
          d[x][y] != d[now.x][now.y] - 1)
        continue;
      Q.push((Point){x, y});
    }
  }
}

int main() {
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= n; i++) {
    scanf("%s", s[i] + 1);
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &cost[i][j]);
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &on[i][j]);
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &off[i][j]);
    }
  }
  for (int i = 1; i <= q; i++) {
    scanf("%d%d", &x[i], &y[i]);
    x[i]++;
    y[i]++;
  }
  t[x[1]][y[1]].push_back(0);
  for (int i = 2; i <= q; i++) {
    work(x[i - 1], y[i - 1], x[i], y[i]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (t[i][j].size() >= 1) {
        ans = ans + on[i][j] + off[i][j];
      }
      for (int k = 1; k < (int)t[i][j].size(); k++) {
        ans += min(on[i][j] + off[i][j],
                   (t[i][j][k] - t[i][j][k - 1]) * cost[i][j]);
      }
    }
  }
  printf("%d\\n", ans);
  return 0;
}

Error: TLE

Fixed submission:

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

#define wh while
#define inf (int)(~0u / 2)
#define FOR(i, n) for (int i = 0; i < n; i++)
#define FOR1(i, n) for (int i = 1; i < n; i++)
#define FOR2(i, n) for (int i = 0; i <= n; i++)
#define REP(i, n) for (int i = 1; i <= n; i++)
#define FORI(it, n) for (typeof(n.begin()) it = n.begin(); it != n.end(); it++)
#define sf scanf
#define pf printf
#define frs first
#define sec second
#define psh push_back
#define mkp make_pair
#define PB(x) push_back(x)
#define MP(x, y) make_pair(x, y)
#define clr(abc, z) memset(abc, z, sizeof(abc))

typedef long long LL;
typedef long double LD;

const int maxn = 55;
struct NODE {
  map<int, int> mp[maxn];
  int step, cost;
  int x, y;
};
char mp[maxn][maxn];
bool vis[maxn][maxn];
int on_cost[maxn][maxn];
int open_cost[maxn][maxn];
int close_cost[maxn][maxn];
int endx[1100], endy[1100];
int R, C, M;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
bool isOK(int x, int y) {
  if (x >= 0 && x < R && y >= 0 && y < C && mp[x][y] != '#' && !vis[x][y])
    return true;
  return false;
}
NODE bfs(NODE st, int ed) {
  queue<NODE> Q;
  Q.push(st);
  while (!Q.empty()) {
    NODE now = Q.front();
    Q.pop();
    if (now.x == endx[ed] && now.y == endy[ed])
      return now;
    vis[now.x][now.y] = true;
    FOR(i, 4) {
      NODE s = now;
      if (isOK(now.x + dx[i], now.y + dy[i])) {
        s.x += dx[i];
        s.y += dy[i];
        s.step++;
        if (s.mp[s.x][s.y]) {
          if ((open_cost[s.x][s.y] + close_cost[s.x][s.y]) >
              ((s.step - s.mp[s.x][s.y]) * on_cost[s.x][s.y]))
            s.cost += (s.step - s.mp[s.x][s.y]) * on_cost[s.x][s.y];
          else
            s.cost += (open_cost[s.x][s.y] + close_cost[s.x][s.y]);
        } else
          s.cost += (open_cost[s.x][s.y] + close_cost[s.x][s.y]);
        s.mp[s.x][s.y] = s.step;
        vis[s.x][s.y] = true;
        Q.push(s);
      }
    }
  }
}

int main() {
  sf("%d%d%d", &R, &C, &M);
  FOR(i, R) sf("%s", mp[i]);
  FOR(i, R) FOR(j, C) sf("%d", &on_cost[i][j]);
  FOR(i, R) FOR(j, C) sf("%d", &open_cost[i][j]);
  FOR(i, R) FOR(j, C) sf("%d", &close_cost[i][j]);
  FOR(i, M) sf("%d%d", &endx[i], &endy[i]);
  NODE st;
  st.x = endx[0];
  st.y = endy[0];
  st.step = 1;
  st.cost = close_cost[st.x][st.y] + open_cost[st.x][st.y];
  st.mp[st.x][st.y] = st.step;
  for (int i = 1; i < M; i++) {
    clr(vis, 0);
    st = bfs(st, i);
  }
  pf("%d\\n", st.cost);
}