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

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct p1 {
  int idx, x, y;
};
bool operator<(const p1 &r1, const p1 &r2) {
  if (r1.y != r2.y)
    return r1.y < r2.y;
  return r1.x < r2.x;
}
struct edge {
  int to;
  long long cost;
  int type;
};
bool operator<(const edge &e1, const edge &e2) { return e1.cost < e2.cost; }
int H, W, N;
int main() {
  cin >> W >> H >> N;
  vector<p1> p(N);
  for (int i = 0; i < N; i++)
    cin >> p[i].x >> p[i].y, p[i].x--, p[i].y--, p[i].idx = i;
  p.push_back(p1{N, W - 1, H - 1});
  N++;
  vector<vector<p1>> ex(W), ey(H);
  for (int i = 0; i < N; i++) {
    ex[p[i].x].push_back(p[i]);
    ey[p[i].y].push_back(p[i]);
  }
  for (int i = 0; i < W; i++)
    sort(ex[i].begin(), ex[i].end());
  for (int i = 0; i < H; i++)
    sort(ey[i].begin(), ey[i].end());
  vector<vector<edge>> G(N);
  for (int i = 0; i < W; i++) {
    for (int j = 1; j < ex[i].size(); j++) {
      int d = ex[i][j].y - ex[i][j - 1].y;
      G[ex[i][j - 1].idx].push_back(edge{ex[i][j].idx, d, 0});
      G[ex[i][j].idx].push_back(edge{ex[i][j - 1].idx, d, 0});
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 1; j < ey[i].size(); j++) {
      int d = ey[i][j].x - ey[i][j - 1].x;
      G[ey[i][j - 1].idx].push_back(edge{ey[i][j].idx, d, 1});
      G[ey[i][j].idx].push_back(edge{ey[i][j - 1].idx, d, 1});
    }
  }
  priority_queue<edge> que;
  vector<vector<long long>> dist(N, vector<long long>(2, 1LL << 60));
  if (ex[0].size()) {
    que.push(edge{ex[0][0].idx, ex[0][0].y, 0});
    dist[ex[0][0].idx][0] = ex[0][0].y;
  }
  while (!que.empty()) {
    edge u = que.top();
    que.pop();
    for (edge e : G[u.to]) {
      long long d = dist[u.to][u.type];
      if (e.type == 0)
        d += abs(p[u.to].y - p[e.to].y);
      else
        d += abs(p[u.to].x - p[e.to].x);
      if (u.type != e.type)
        d++;
      if (dist[e.to][e.type] > d) {
        dist[e.to][e.type] = d;
        que.push(edge{e.to, -d, e.type});
      }
    }
  }
  long long ret = min(dist[N - 1][0], dist[N - 1][1]);
  if (ret == (1LL << 60))
    cout << -1 << endl;
  else
    cout << ret << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct p1 {
  int idx, x, y;
};
bool operator<(const p1 &r1, const p1 &r2) {
  if (r1.y != r2.y)
    return r1.y < r2.y;
  return r1.x < r2.x;
}
struct edge {
  int to;
  long long cost;
  int type;
};
bool operator<(const edge &e1, const edge &e2) { return e1.cost < e2.cost; }
int H, W, N;
int main() {
  cin >> W >> H >> N;
  vector<p1> p(N);
  for (int i = 0; i < N; i++)
    cin >> p[i].x >> p[i].y, p[i].x--, p[i].y--, p[i].idx = i;
  p.push_back(p1{N, W - 1, H - 1});
  N++;
  vector<vector<p1>> ex(W), ey(H);
  for (int i = 0; i < N; i++) {
    ex[p[i].x].push_back(p[i]);
    ey[p[i].y].push_back(p[i]);
  }
  for (int i = 0; i < W; i++)
    sort(ex[i].begin(), ex[i].end());
  for (int i = 0; i < H; i++)
    sort(ey[i].begin(), ey[i].end());
  vector<vector<edge>> G(N);
  for (int i = 0; i < W; i++) {
    for (int j = 1; j < ex[i].size(); j++) {
      int d = ex[i][j].y - ex[i][j - 1].y;
      G[ex[i][j - 1].idx].push_back(edge{ex[i][j].idx, d, 0});
      G[ex[i][j].idx].push_back(edge{ex[i][j - 1].idx, d, 0});
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 1; j < ey[i].size(); j++) {
      int d = ey[i][j].x - ey[i][j - 1].x;
      G[ey[i][j - 1].idx].push_back(edge{ey[i][j].idx, d, 1});
      G[ey[i][j].idx].push_back(edge{ey[i][j - 1].idx, d, 1});
    }
  }
  priority_queue<edge> que;
  vector<long long> dist(N, -1);
  if (ex[0].size()) {
    que.push(edge{ex[0][0].idx, ex[0][0].y, 0});
    dist[ex[0][0].idx] = ex[0][0].y;
  }
  while (!que.empty()) {
    edge u = que.top();
    que.pop();
    for (edge e : G[u.to]) {
      long long d = u.cost;
      if (e.type == 0)
        d += abs(p[u.to].y - p[e.to].y);
      else
        d += abs(p[u.to].x - p[e.to].x);
      if (u.type != e.type)
        d++;
      if (dist[e.to] > d || dist[e.to] == -1) {
        dist[e.to] = d;
        que.push(edge{e.to, d, e.type});
      }
    }
  }
  cout << dist[N - 1] << endl;
  return 0;
}