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

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define int long long
#define endl "\\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

struct fast_io {
  fast_io() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
  };
} fio;

int H, W, K;
vector<string> c;

int dijkstra(int sy, int sx, int gy, int gx) {
  priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>,
                 greater<pair<int, pair<int, int>>>>
      q;

  vector<vector<int>> used(H, vector<int>(W, 0));
  vector<vector<int>> used2(H, vector<int>(W, 0));
  vector<vector<int>> d(H, vector<int>(W, INF));

  d[sy][sx] = 0;
  q.push({0, {sy, sx}});

  while (!q.empty()) {
    pair<int, pair<int, int>> p = q.top();
    q.pop();
    int x = p.second.second;
    int y = p.second.first;
    int cost = p.first;

    // cout<<"y = "<<y<<" x = "<<x<<" cost = "<<cost<<endl;

    if (d[y][x] < cost)
      continue;

    // if(y == gy && gx == x) return cost;

    // if(!(used[y][x] & 1)) {
    if (used[y][x] <= 100) {
      for (int i = x + 1; i < W; i++) {
        if (c[y][i] == '@')
          break;

        int ncost = (i - x - 1) / K + 1;

        // used[y][i] |= 1;
        used[y][i]++;

        if (ncost + cost < d[y][i]) {
          d[y][i] = ncost + cost;
          // used[y][i] = 0;
          // used[y][i] &= 1;
          q.push({d[y][i], {y, i}});
        }
      }

      for (int i = x - 1; i >= 0; i--) {
        if (c[y][i] == '@')
          break;

        int ncost = (x - i - 1) / K + 1;

        // used[y][i] |= 1;
        used[y][i]++;

        if (ncost + cost < d[y][i]) {
          d[y][i] = ncost + cost;
          // used[y][i] = 0;
          // used[y][i] &= 1;
          q.push({d[y][i], {y, i}});
        }
      }
    }

    // if(!(used[y][x] & 2)) {
    if (used2[y][x] <= 100) {
      for (int i = y + 1; i < H; i++) {
        if (c[i][x] == '@')
          break;

        int ncost = (i - y - 1) / K + 1;

        // used[i][x] |= 2;
        used2[i][x]++;

        if (ncost + cost < d[i][x]) {
          d[i][x] = ncost + cost;
          used[i][x] = 0;
          q.push({d[i][x], {i, x}});
        }
      }

      for (int i = y - 1; i >= 0; i--) {
        if (c[i][x] == '@')
          break;

        int ncost = (y - i - 1) / K + 1;

        // used[i][x] |= 2;
        used2[i][x]++;

        if (ncost + cost < d[i][x]) {
          d[i][x] = ncost + cost;
          used[i][x] = 0;
          q.push({d[i][x], {i, x}});
        }
      }
    }
  }

  return d[gy][gx];
  // exit(2);
  // return -1;
}

class union_find {
  int _setnum;
  vector<int> par, nume;

public:
  union_find() {}

  union_find(int x) {
    par.resize(x);
    nume.resize(x);
    init();
  }

  ~union_find() {
    //
  }

  void clear() {
    _setnum = 0;
    par.clear();
    nume.clear();
  }

  void init() {
    _setnum = par.size();
    for (int i = 0; i < par.size(); i++) {
      par[i] = i;
      nume[i] = 1;
    }
  }

  void resize(int x) {

    par.resize(x);
    nume.resize(x);
    init();
  }

  int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    _setnum--;

    if (nume[x] > nume[y])
      std::swap(x, y);

    par[x] = y;
    nume[y] += nume[x];
  }

  bool same(int x, int y) { return find(x) == find(y); }

  int numel(int x) { return nume[find(x)]; }

  int size() { return par.size(); }

  int setnum() { return _setnum; }
};

signed main() {
  cout << fixed << setprecision(10);

  int x1, y1, x2, y2;
  union_find uf;

  cin >> H >> W >> K;

  uf.resize(H * W);

  cin >> x1 >> y1 >> x2 >> y2;

  x1--;
  y1--;
  x2--;
  y2--;

  c.resize(H);

  for (int i = 0; i < H; i++) {
    cin >> c[i];
  }

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (c[i][j] == '@')
        continue;

      if (i + 1 < H) {
        if (c[i + 1][j] != '@')
          uf.unite(i * W + j, (i + 1) * W + j);
        // cout<<"<>"<<endl;
      }
      if (j + 1 < W) {
        if (c[i][j + 1] != '@')
          uf.unite(i * W + j, i * W + j + 1);
        // cout<<"[]"<<endl;
      }
    }
  }

  // for(int i = 0; i < H; i++){
  // for(int j = 0; j < W; j++){
  // cout<<uf.find(i * W + j)<<" ";
  // }
  // cout<<endl;
  // }

  if (uf.same(x1 * W + y1, x2 * W + y2) == false) {
    cout << -1 << endl;
    return 0;
  }

  cout << dijkstra(x1, y1, x2, y2) << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define int long long
#define endl "\\n"

constexpr long long INF = (long long)1e18;
constexpr long long MOD = 1'000'000'007;

struct fast_io {
  fast_io() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
  };
} fio;

int H, W, K;
vector<string> c;

int dijkstra(int sy, int sx, int gy, int gx) {
  priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>,
                 greater<pair<int, pair<int, int>>>>
      q;

  vector<vector<int>> used(H, vector<int>(W, 0));
  vector<vector<int>> d(H, vector<int>(W, INF));

  d[sy][sx] = 0;
  q.push({0, {sy, sx}});

  while (!q.empty()) {
    pair<int, pair<int, int>> p = q.top();
    q.pop();
    int x = p.second.second;
    int y = p.second.first;
    int cost = p.first;

    // cout<<"y = "<<y<<" x = "<<x<<" cost = "<<cost<<endl;

    if (d[y][x] < cost)
      continue;

    if (y == gy && gx == x)
      return cost;

    if (!(used[y][x] & 1)) {
      for (int i = x + 1; i < W; i++) {
        if (c[y][i] == '@')
          break;

        int ncost = (i - x - 1) / K + 1;

        // used[y][i] |= 1;

        if (ncost + cost < d[y][i]) {
          d[y][i] = ncost + cost;
          used[y][i] = 0;
          // used[y][i] &= 1;
          q.push({d[y][i], {y, i}});
        }
      }

      for (int i = x - 1; i >= 0; i--) {
        if (c[y][i] == '@')
          break;

        int ncost = (x - i - 1) / K + 1;

        // used[y][i] |= 1;

        if (ncost + cost < d[y][i]) {
          d[y][i] = ncost + cost;
          used[y][i] = 0;
          // used[y][i] &= 1;
          q.push({d[y][i], {y, i}});
        }
      }
    }

    if (!(used[y][x] & 2)) {
      for (int i = y + 1; i < H; i++) {
        if (c[i][x] == '@')
          break;

        int ncost = (i - y - 1) / K + 1;

        // used[i][x] |= 2;

        if (ncost + cost < d[i][x]) {
          d[i][x] = ncost + cost;
          used[i][x] = 0;
          q.push({d[i][x], {i, x}});
        }
      }

      for (int i = y - 1; i >= 0; i--) {
        if (c[i][x] == '@')
          break;

        int ncost = (y - i - 1) / K + 1;

        // used[i][x] |= 2;

        if (ncost + cost < d[i][x]) {
          d[i][x] = ncost + cost;
          used[i][x] = 0;
          q.push({d[i][x], {i, x}});
        }
      }
    }
  }

  exit(2);
  return -1;
}

class union_find {
  int _setnum;
  vector<int> par, nume;

public:
  union_find() {}

  union_find(int x) {
    par.resize(x);
    nume.resize(x);
    init();
  }

  ~union_find() {
    //
  }

  void clear() {
    _setnum = 0;
    par.clear();
    nume.clear();
  }

  void init() {
    _setnum = par.size();
    for (int i = 0; i < par.size(); i++) {
      par[i] = i;
      nume[i] = 1;
    }
  }

  void resize(int x) {

    par.resize(x);
    nume.resize(x);
    init();
  }

  int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);

    if (x == y)
      return;

    _setnum--;

    if (nume[x] > nume[y])
      std::swap(x, y);

    par[x] = y;
    nume[y] += nume[x];
  }

  bool same(int x, int y) { return find(x) == find(y); }

  int numel(int x) { return nume[find(x)]; }

  int size() { return par.size(); }

  int setnum() { return _setnum; }
};

signed main() {
  cout << fixed << setprecision(10);

  int x1, y1, x2, y2;
  union_find uf;

  cin >> H >> W >> K;

  uf.resize(H * W);

  cin >> x1 >> y1 >> x2 >> y2;

  x1--;
  y1--;
  x2--;
  y2--;

  c.resize(H);

  for (int i = 0; i < H; i++) {
    cin >> c[i];
  }

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (c[i][j] == '@')
        continue;

      if (i + 1 < H) {
        if (c[i + 1][j] != '@')
          uf.unite(i * W + j, (i + 1) * W + j);
        // cout<<"<>"<<endl;
      }
      if (j + 1 < W) {
        if (c[i][j + 1] != '@')
          uf.unite(i * W + j, i * W + j + 1);
        // cout<<"[]"<<endl;
      }
    }
  }

  // for(int i = 0; i < H; i++){
  // for(int j = 0; j < W; j++){
  // cout<<uf.find(i * W + j)<<" ";
  // }
  // cout<<endl;
  // }

  if (uf.same(x1 * W + y1, x2 * W + y2) == false) {
    cout << -1 << endl;
    return 0;
  }

  cout << dijkstra(x1, y1, x2, y2) << endl;

  return 0;
}