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

#include <bits/stdc++.h>
using namespace std;
// typedef long long int;
const int INF = INT_MAX;

template <class T> pair<vector<T>, map<T, int>> compress(vector<T> &a) {
  vector<T> v;
  for (int i = 0; i < a.size(); i++)
    v.push_back(a[i]);
  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
  map<T, int> m;
  for (int i = 0; i < v.size(); i++)
    m[v[i]] = i;
  return {v, m};
}

struct edge {
  int x, y, z;
  int cost;
};

struct S {
  int x, y, z;
  int cost;

  bool operator<(const S &x) const { return cost > x.cost; }
};

using P = pair<int, int>;
vector<edge> G[300][300][11];
int dist[300][300][11];
int sum[300][300];

int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, M, K, R;
  vector<int> X(100), Y(100), Z(100), xl(50), xr(50), yt(50), yb(50), h(50);
  while (cin >> N, N) {
    cin >> M >> K >> R;

    vector<int> xs, ys;
    for (int i = 0; i < N; i++) {
      cin >> X[i] >> Y[i] >> Z[i];
      xs.push_back(X[i]);
      ys.push_back(Y[i]);
    }
    for (int i = 0; i < M; i++) {
      cin >> xl[i] >> yt[i] >> xr[i] >> yb[i] >> h[i];
      xs.push_back(xl[i]);
      xs.push_back(xr[i]);
      ys.push_back(yt[i]);
      ys.push_back(yb[i]);
      if (h[i] == K) {
        if (xl[i] - 1 >= 1)
          xs.push_back(xl[i] - 1);
        if (xr[i] + 1 <= R)
          xs.push_back(xr[i] + 1);
        if (yt[i] - 1 >= 1)
          ys.push_back(yt[i] - 1);
        if (yb[i] + 1 <= R)
          ys.push_back(yb[i] + 1);
      }
    }

    auto zipX = compress(xs);
    auto zipY = compress(ys);

    int XN = zipX.first.size();
    int YN = zipY.first.size();

    for (int k = 1; k <= K; k++) {
      for (int i = 0; i < XN; i++) {
        for (int j = 0; j < YN; j++) {
          G[i][j][k].clear();
        }
      }
    }

    for (int k = 1; k <= K; k++) {
      for (int i = 0; i < XN; i++) {
        for (int j = 0; j < YN; j++) {
          int cx = zipX.first[i];
          int cy = zipY.first[j];
          if (k == K) {
            for (int l = 0; l < 4; l++) {
              if (i + dx[l] < 0 || XN <= i + dx[l])
                continue;
              if (j + dy[l] < 0 || YN <= j + dy[l])
                continue;
              int nx = zipX.first[i + dx[l]];
              int ny = zipY.first[j + dy[l]];
              int cost = abs(cx - nx) + abs(cy - ny);
              G[i][j][k].push_back({i + dx[l], j + dy[l], k, cost});
            }
          } else {

            for (int m = 0; m < M; m++) {
              if (k + 1 != h[m])
                continue;
              int cost = INF;
              int ii = 0, jj = 0;
              int li = zipX.second[xl[m]];
              int ri = zipX.second[xr[m]];
              int tj = zipY.second[yt[m]];
              int bj = zipY.second[yb[m]];
              if (li <= i && i <= ri && tj <= j && j <= bj) {
                if (cost > 100) {
                  cost = 100;
                  ii = i, jj = j;
                }
              } else if (li <= i && i <= ri) {
                if (cost > 100 + abs(cy - yt[m])) {
                  cost = 100 + abs(cy - yt[m]);
                  ii = i, jj = tj;
                }
                if (cost > 100 + abs(cy - yb[m])) {
                  cost = 100 + abs(cy - yb[m]);
                  ii = i, jj = bj;
                }
              } else if (tj <= j && j <= bj) {
                if (cost > 100 + abs(cx - xl[m])) {
                  cost = 100 + abs(cx - xl[m]);
                  ii = li, jj = j;
                }
                if (cost > 100 + abs(cx - xr[m])) {
                  cost = 100 + abs(cx - xr[m]);
                  ii = ri, jj = j;
                }
              } else {
                if (cost > 100 + abs(cx - xl[m]) + abs(cy - yt[m])) {
                  cost = 100 + abs(cx - xl[m]) + abs(cy - yt[m]);
                  ii = li, jj = tj;
                }
                if (cost > 100 + abs(cx - xr[m]) + abs(cy - yt[m])) {
                  cost = 100 + abs(cx - xr[m]) + abs(cy - yt[m]);
                  ii = ri, jj = tj;
                }
                if (cost > 100 + abs(cx - xl[m]) + abs(cy - yb[m])) {
                  cost = 100 + abs(cx - xl[m]) + abs(cy - yb[m]);
                  ii = li, jj = bj;
                }
                if (cost > 100 + abs(cx - xr[m]) + abs(cy - yb[m])) {
                  cost = 100 + abs(cx - xr[m]) + abs(cy - yb[m]);
                  ii = ri, jj = bj;
                }
              }
              G[i][j][k].push_back({ii, jj, k + 1, cost});
            }
          }
        }
      }
    }

    vector<P> goal;
    for (int i = 0; i < XN; i++) {
      for (int j = 0; j < YN; j++) {
        int cx = zipX.first[i];
        int cy = zipY.first[j];
        bool ok = true;
        for (int m = 0; m < M; m++) {
          if (K == h[m] && xl[m] <= cx && cx <= xr[m] && yt[m] <= cy &&
              cy <= yb[m]) {
            ok = false;
            break;
          }
        }
        if (ok)
          goal.push_back({i, j});
      }
    }

    memset(sum, 0, sizeof sum);
    for (int n = 0; n < N; n++) {
      for (int k = 1; k <= K; k++) {
        for (int i = 0; i < XN; i++) {
          for (int j = 0; j < YN; j++) {
            dist[i][j][k] = INF;
          }
        }
      }
      dist[zipX.second[X[n]]][zipY.second[Y[n]]][Z[n]] = 0;
      priority_queue<S> q;
      q.push({zipX.second[X[n]], zipY.second[Y[n]], Z[n], 0});
      while (q.size()) {
        S s = q.top();
        q.pop();
        if (dist[s.x][s.y][s.z] < s.cost)
          continue;
        // cout << s.cost << endl;
        for (auto &e : G[s.x][s.y][s.z]) {
          int ncost = s.cost + e.cost;
          if (dist[e.x][e.y][e.z] > ncost) {
            dist[e.x][e.y][e.z] = ncost;
            q.push({e.x, e.y, e.z, ncost});
          }
        }
      }
      for (auto &g : goal) {
        sum[g.first][g.second] += dist[g.first][g.second][K];
      }
    }
    int ans = INF;
    for (auto &g : goal) {
      ans = min(ans, sum[g.first][g.second]);
    }
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1LL << 60;

template <class T> pair<vector<T>, map<T, int>> compress(vector<T> &a) {
  vector<T> v;
  for (int i = 0; i < a.size(); i++)
    v.push_back(a[i]);
  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
  map<T, int> m;
  for (int i = 0; i < v.size(); i++)
    m[v[i]] = i;
  return {v, m};
}

struct edge {
  int x, y, z;
  ll cost;
};

struct S {
  int x, y, z;
  ll cost;

  bool operator<(const S &x) const { return cost > x.cost; }
};

using P = pair<int, int>;
list<edge> G[300][300][11];
ll dist[300][300][11];
ll sum[300][300];

int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, M, K, R;
  vector<int> X(100), Y(100), Z(100), xl(50), xr(50), yt(50), yb(50), h(50);
  while (cin >> N, N) {
    cin >> M >> K >> R;

    vector<int> xs, ys;
    for (int i = 0; i < N; i++) {
      cin >> X[i] >> Y[i] >> Z[i];
      xs.push_back(X[i]);
      ys.push_back(Y[i]);
    }
    for (int i = 0; i < M; i++) {
      cin >> xl[i] >> yt[i] >> xr[i] >> yb[i] >> h[i];
      xs.push_back(xl[i]);
      xs.push_back(xr[i]);
      ys.push_back(yt[i]);
      ys.push_back(yb[i]);
      if (h[i] == K) {
        if (xl[i] - 1 >= 1)
          xs.push_back(xl[i] - 1);
        if (xr[i] + 1 <= R)
          xs.push_back(xr[i] + 1);
        if (yt[i] - 1 >= 1)
          ys.push_back(yt[i] - 1);
        if (yb[i] + 1 <= R)
          ys.push_back(yb[i] + 1);
      }
    }

    auto zipX = compress(xs);
    auto zipY = compress(ys);

    int XN = zipX.first.size();
    int YN = zipY.first.size();

    for (int k = 1; k <= K; k++) {
      for (int i = 0; i < XN; i++) {
        for (int j = 0; j < YN; j++) {
          G[i][j][k].clear();
        }
      }
    }

    for (int k = 1; k <= K; k++) {
      for (int i = 0; i < XN; i++) {
        for (int j = 0; j < YN; j++) {
          int cx = zipX.first[i];
          int cy = zipY.first[j];
          if (k == K) {
            for (int l = 0; l < 4; l++) {
              if (i + dx[l] < 0 || XN <= i + dx[l])
                continue;
              if (j + dy[l] < 0 || YN <= j + dy[l])
                continue;
              int nx = zipX.first[i + dx[l]];
              int ny = zipY.first[j + dy[l]];
              ll cost = abs(cx - nx) + abs(cy - ny);
              G[i][j][k].push_back({i + dx[l], j + dy[l], k, cost});
            }
          } else {

            for (int m = 0; m < M; m++) {
              if (k + 1 != h[m])
                continue;
              ll cost = INF;
              int ii = 0, jj = 0;
              int li = zipX.second[xl[m]];
              int ri = zipX.second[xr[m]];
              int tj = zipY.second[yt[m]];
              int bj = zipY.second[yb[m]];
              if (li <= i && i <= ri && tj <= j && j <= bj) {
                if (cost > 100) {
                  cost = 100;
                  ii = i, jj = j;
                }
              } else if (li <= i && i <= ri) {
                if (cost > 100 + abs(cy - yt[m])) {
                  cost = 100 + abs(cy - yt[m]);
                  ii = i, jj = tj;
                }
                if (cost > 100 + abs(cy - yb[m])) {
                  cost = 100 + abs(cy - yb[m]);
                  ii = i, jj = bj;
                }
              } else if (tj <= j && j <= bj) {
                if (cost > 100 + abs(cx - xl[m])) {
                  cost = 100 + abs(cx - xl[m]);
                  ii = li, jj = j;
                }
                if (cost > 100 + abs(cx - xr[m])) {
                  cost = 100 + abs(cx - xr[m]);
                  ii = ri, jj = j;
                }
              } else {
                if (cost > 100 + abs(cx - xl[m]) + abs(cy - yt[m])) {
                  cost = 100 + abs(cx - xl[m]) + abs(cy - yt[m]);
                  ii = li, jj = tj;
                }
                if (cost > 100 + abs(cx - xr[m]) + abs(cy - yt[m])) {
                  cost = 100 + abs(cx - xr[m]) + abs(cy - yt[m]);
                  ii = ri, jj = tj;
                }
                if (cost > 100 + abs(cx - xl[m]) + abs(cy - yb[m])) {
                  cost = 100 + abs(cx - xl[m]) + abs(cy - yb[m]);
                  ii = li, jj = bj;
                }
                if (cost > 100 + abs(cx - xr[m]) + abs(cy - yb[m])) {
                  cost = 100 + abs(cx - xr[m]) + abs(cy - yb[m]);
                  ii = ri, jj = bj;
                }
              }
              G[i][j][k].push_back({ii, jj, k + 1, cost});
            }
          }
        }
      }
    }

    vector<P> goal;
    for (int i = 0; i < XN; i++) {
      for (int j = 0; j < YN; j++) {
        int cx = zipX.first[i];
        int cy = zipY.first[j];
        bool ok = true;
        for (int m = 0; m < M; m++) {
          if (K == h[m] && xl[m] <= cx && cx <= xr[m] && yt[m] <= cy &&
              cy <= yb[m]) {
            ok = false;
            break;
          }
        }
        if (ok)
          goal.push_back({i, j});
      }
    }

    memset(sum, 0, sizeof sum);
    for (int n = 0; n < N; n++) {
      for (int k = 1; k <= K; k++) {
        for (int i = 0; i < XN; i++) {
          for (int j = 0; j < YN; j++) {
            dist[i][j][k] = INF;
          }
        }
      }
      dist[zipX.second[X[n]]][zipY.second[Y[n]]][Z[n]] = 0;
      priority_queue<S> q;
      q.push({zipX.second[X[n]], zipY.second[Y[n]], Z[n], 0});
      while (q.size()) {
        S s = q.top();
        q.pop();
        if (dist[s.x][s.y][s.z] < s.cost)
          continue;
        // cout << s.cost << endl;
        for (auto &e : G[s.x][s.y][s.z]) {
          ll ncost = s.cost + e.cost;
          if (dist[e.x][e.y][e.z] > ncost) {
            dist[e.x][e.y][e.z] = ncost;
            q.push({e.x, e.y, e.z, ncost});
          }
        }
      }
      for (auto &g : goal) {
        sum[g.first][g.second] += dist[g.first][g.second][K];
      }
    }
    ll ans = INF;
    for (auto &g : goal) {
      ans = min(ans, sum[g.first][g.second]);
    }
    cout << ans << endl;
  }
}