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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define int long long

#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai                                                               \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vpii = vector<pii>;

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> p) {
  os << "(" << p.fst << ", " << p.scd << ")";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> v) {
  rep(i, v.size()) {
    if (i)
      os << ", ";
    os << v[i];
  }
  return os;
}
template <typename T> T &max(T &a, T &b) {
  if (a >= b)
    return a;
  return b;
}
template <typename T> T &min(T &a, T &b) {
  if (a < b)
    return a;
  return b;
}
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
int in() {
  int a;
  scanf("%d", &a);
  return a;
}
ll lin() {
  ll a;
  scanf("%lld", &a);
  return a;
}

constexpr int inf = 1e9;
constexpr ll linf = 3e18;
constexpr double eps = 1e-9;

typedef pii Pos;
typedef pair<Pos, bool> State; // ??§?¨?, ????????????????????????
typedef pair<int, State> Data;

int M, N, K;

vi row[100010];
vi col[100010];
map<State, int> d;
priority_queue<Data, vector<Data>, greater<Data>> q;

void queue_init() {
  int x = 0;
  if (row[x].empty())
    return;
  int yidx = lower_bound(all(row[x]), 0) - begin(row[x]);

  q.push(Data(row[x][yidx], State(Pos(row[x][yidx], 0), true)));
  if (yidx == 0) {
    q.push(Data(1, State(Pos(0, 0), false)));
  }
}

signed main() {
  M = lin(), N = lin(), K = lin();

  rep(i, K) {
    int x = lin() - 1, y = lin() - 1;

    row[x].PB(y);
    col[y].PB(x);
  }

  row[M - 1].PB(N - 1);
  col[N - 1].PB(M - 1);

  rep(i, 100010) sort(all(row[i])), sort(all(col[i]));

  Pos start = Pos(0, 0);
  Pos goal = Pos(N - 1, M - 1);

  d[State(start, true)] = 0;

  queue_init();

  while (q.size()) {
    Data dat = q.top();
    q.pop();

    State state = dat.scd;
    Pos p = state.fst;
    int y = p.fst, x = p.scd;
    bool is_vertical = state.scd;
    int dist = dat.fst;

    if (d.find(state) != d.end() && d[state] < dist)
      continue;

    int yidx = lower_bound(all(row[x]), y) - begin(row[x]);
    int xidx = lower_bound(all(col[y]), x) - begin(col[y]);

    if (yidx - 1 >= 0) {
      int nxdist = dist + abs(y - row[x][yidx - 1]) + (is_vertical ? 0 : 1);
      Pos nxpos = Pos(row[x][yidx - 1], x);
      State nxstate = State(nxpos, true);

      if (d.find(nxstate) == d.end() || d[nxstate] > nxdist) {
        d[nxstate] = nxdist;

        q.push(Data(nxdist, nxstate));
      }
    }

    if (yidx + 1 < row[x].size()) {
      int nxdist = dist + abs(y - row[x][yidx + 1]) + (is_vertical ? 0 : 1);
      Pos nxpos = Pos(row[x][yidx + 1], x);
      State nxstate = State(nxpos, true);

      if (d.find(nxstate) == d.end() || d[nxstate] > nxdist) {
        d[nxstate] = nxdist;

        q.push(Data(nxdist, nxstate));
      }
    }

    if (xidx - 1 >= 0) {
      int nxdist = dist + abs(x - col[y][xidx - 1]) + (is_vertical ? 1 : 0);
      Pos nxpos = Pos(y, col[y][xidx - 1]);
      State nxstate = State(nxpos, false);

      if (d.find(nxstate) == d.end() || d[nxstate] > nxdist) {
        d[nxstate] = nxdist;

        q.push(Data(nxdist, nxstate));
      }
    }

    if (xidx + 1 < col[y].size()) {
      int nxdist = dist + abs(x - col[y][xidx + 1]) + (is_vertical ? 1 : 0);
      Pos nxpos = Pos(y, col[y][xidx + 1]);
      State nxstate = State(nxpos, false);

      if (d.find(nxstate) == d.end() || d[nxstate] > nxdist) {
        d[nxstate] = nxdist;

        q.push(Data(nxdist, nxstate));
      }
    }
  }

  int ans = linf;

  if (d.find(State(goal, true)) != d.end())
    chmin(ans, d[State(goal, true)]);
  if (d.find(State(goal, false)) != d.end())
    chmin(ans, d[State(goal, false)]);

  printf("%lld\\n", ans == linf ? -1 : ans);
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define int long long

#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai                                                               \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vpii = vector<pii>;

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> p) {
  os << "(" << p.fst << ", " << p.scd << ")";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> v) {
  rep(i, v.size()) {
    if (i)
      os << ", ";
    os << v[i];
  }
  return os;
}
template <typename T> T &max(T &a, T &b) {
  if (a >= b)
    return a;
  return b;
}
template <typename T> T &min(T &a, T &b) {
  if (a < b)
    return a;
  return b;
}
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
int in() {
  int a;
  scanf("%d", &a);
  return a;
}
ll lin() {
  ll a;
  scanf("%lld", &a);
  return a;
}

constexpr int inf = 1e9;
constexpr ll linf = 3e18;
constexpr double eps = 1e-9;

typedef pii Pos;
typedef pair<Pos, bool> State; // ??§?¨?, ????????????????????????
typedef pair<int, State> Data;

int M, N, K;

vi row[100010];
vi col[100010];
map<State, int> d;

signed main() {
  M = lin(), N = lin(), K = lin();

  rep(i, K) {
    int x = lin() - 1, y = lin() - 1;

    row[x].PB(y);
    col[y].PB(x);
  }

  row[M - 1].PB(N - 1);
  col[N - 1].PB(M - 1);

  Pos start = Pos(0, 0);
  Pos goal = Pos(N - 1, M - 1);

  priority_queue<Data, vector<Data>, greater<Data>> q;
  d[State(start, true)] = 0;
  q.push(Data(0, State(start, true)));

  while (q.size()) {
    Data dat = q.top();
    q.pop();

    State state = dat.scd;
    Pos p = state.fst;
    int y = p.fst, x = p.scd;
    bool is_vertical = state.scd;
    int dist = dat.fst;

    if (d.find(state) != d.end() && d[state] < dist)
      continue;

    if (is_vertical) { // ?????????????????????
      rep(i, row[x].size()) {
        int nxdist = dist + abs(y - row[x][i]);
        Pos nxpos = Pos(row[x][i], x);

        if (nxpos != start && dist == nxdist)
          continue;

        if (nxpos == goal) {
          printf("%lld\\n", nxdist);
          goto end;
        }

        State nxstate = State(nxpos, !is_vertical);

        if (d.find(nxstate) == d.end() || d[nxstate] > nxdist + 1) {
          d[nxstate] = nxdist + 1;

          q.push(Data(nxdist + 1, nxstate));
        }
      }
    } else { // ?¨???????????????????
      rep(i, col[y].size()) {
        int nxdist = dist + abs(x - col[y][i]);
        Pos nxpos = Pos(y, col[y][i]);

        if (nxpos != start && dist == nxdist)
          continue;

        if (nxpos == goal) {
          printf("%lld\\n", nxdist);
          goto end;
        }

        State nxstate = State(nxpos, !is_vertical);

        if (d.find(nxstate) == d.end() || d[nxstate] > nxdist + 1) {
          d[nxstate] = nxdist + 1;

          q.push(Data(nxdist + 1, nxstate));
        }
      }
    }
  }

  puts("-1");

end:;
}