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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int pair_to_int(pair<int, int> pair) {
  return pair.first * 10000 + pair.second;
}
pair<int, int> int_to_pair(int i) {
  int f = i / 10000;
  return make_pair(f, i - f * 10000);
}

int calc_cost(pair<int, int> a, pair<int, int> b) {
  int i = a.first - b.first;
  int j = a.second - b.second;
  int c;
  if (min(abs(i), abs(j)) == 0 && max(abs(i), abs(j)) == 1) {
    c = 0;
  } else {
    c = 1;
  }
  return c;
}

int main() {
  int h, w;
  cin >> h >> w;
  pair<int, int> start, dest;
  cin >> start.first >> start.second;
  start.first--;
  start.second--;
  cin >> dest.first >> dest.second;
  dest.first--;
  dest.second--;

  vector<string> mass(h);
  for (int i = 0; i < h; i++) {
    cin >> mass[i];
  }
  unordered_map<int, vector<int>> to;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      auto a = make_pair(y, x);
      if (mass[a.first][a.second] == '#') {
        continue;
      }
      for (int i = -2; i <= 2; i++) {
        for (int j = -2; j <= 2; j++) {
          if (i == 0 && j == 0) {
            continue;
          }
          auto b = make_pair(y + i, x + j);
          if (b.first < 0 || b.first >= h) {
            continue;
          }
          if (b.second < 0 || b.second >= w) {
            continue;
          }
          if (mass[b.first][b.second] == '#') {
            continue;
          }
          to[pair_to_int(a)].push_back(pair_to_int(b));
          to[pair_to_int(b)].push_back(pair_to_int(a));
          // cout << "(" << a.first << "," << a.second << ")" << "(" << b.first
          // << "," << b.second << ")" << cost[make_pair(a, b)] << endl;
        }
      }
    }
  }
  // dijkstra
  int NEG_DIST_MAX = -10010010;
  unordered_map<int, int> neg_dist;
  unordered_map<int, bool> visited;

  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      neg_dist[y * 10000 + x] = NEG_DIST_MAX;
      visited[y * 10000 + x] = false;
    }
  }
  neg_dist[pair_to_int(start)] = 0;

  // neg_dist, point
  priority_queue<pair<int, int>> que;
  que.push(make_pair(neg_dist[pair_to_int(start)], pair_to_int(start)));

  while (!que.empty()) {
    // pop maximum neg dist
    auto q = que.top();
    que.pop();
    auto u = q.second;
    if (visited[u]) {
      continue;
    }
    visited[u] = true;

    // cout << q.first << "(" << u.first << "," << u.second << ")" <<
    // mass[u.first][u.second] << endl;
    for (auto v : to[u]) {
      int nd = neg_dist[u] - calc_cost(int_to_pair(u), int_to_pair(v));
      if (neg_dist[v] < nd) {
        neg_dist[v] = nd;
        que.push(make_pair(nd, v));
      }
    }
  }
  if (neg_dist[pair_to_int(dest)] <= NEG_DIST_MAX) {
    cout << "-1" << endl;
  } else {
    cout << -neg_dist[pair_to_int(dest)] << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int pair_to_int(pair<int, int> pair) {
  return pair.first * 10000 + pair.second;
}
pair<int, int> int_to_pair(int i) {
  int f = i / 10000;
  return make_pair(f, i - f * 10000);
}

int main() {
  int h, w;
  cin >> h >> w;
  pair<int, int> start, dest;
  cin >> start.first >> start.second;
  start.first--;
  start.second--;
  cin >> dest.first >> dest.second;
  dest.first--;
  dest.second--;

  vector<string> mass(h);
  for (int i = 0; i < h; i++) {
    cin >> mass[i];
  }
  unordered_map<int, vector<int>> to;
  unordered_map<ll, int> cost;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      auto a = make_pair(y, x);
      if (mass[a.first][a.second] == '#') {
        continue;
      }
      for (int i = -2; i <= 2; i++) {
        for (int j = -2; j <= 2; j++) {
          if (i == 0 && j == 0) {
            continue;
          }
          auto b = make_pair(y + i, x + j);
          if (b.first < 0 || b.first >= h) {
            continue;
          }
          if (b.second < 0 || b.second >= w) {
            continue;
          }
          if (mass[b.first][b.second] == '#') {
            continue;
          }
          to[pair_to_int(a)].push_back(pair_to_int(b));
          to[pair_to_int(b)].push_back(pair_to_int(a));
          int c;
          if (min(abs(i), abs(j)) == 0 && max(abs(i), abs(j)) == 1) {
            c = 0;
          } else {
            c = 1;
          }
          cost[100000000 * (ll)pair_to_int(a) + (ll)pair_to_int(b)] = c;
          cost[100000000 * (ll)pair_to_int(b) + (ll)pair_to_int(a)] = c;
          // cout << "(" << a.first << "," << a.second << ")" << "(" << b.first
          // << "," << b.second << ")" << cost[make_pair(a, b)] << endl;
        }
      }
    }
  }
  // dijkstra
  int NEG_DIST_MAX = -10010010;
  unordered_map<int, int> neg_dist;
  unordered_map<int, bool> visited;

  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      neg_dist[y * 10000 + x] = NEG_DIST_MAX;
      visited[y * 10000 + x] = false;
    }
  }
  neg_dist[pair_to_int(start)] = 0;

  // neg_dist, point
  priority_queue<pair<int, int>> que;
  que.push(make_pair(neg_dist[pair_to_int(start)], pair_to_int(start)));

  while (!que.empty()) {
    // pop maximum neg dist
    auto q = que.top();
    que.pop();
    auto u = q.second;
    if (visited[u]) {
      continue;
    }
    visited[u] = true;

    // cout << q.first << "(" << u.first << "," << u.second << ")" <<
    // mass[u.first][u.second] << endl;
    for (auto v : to[u]) {
      int nd = neg_dist[u] - cost[100000000 * (ll)u + (ll)v];
      if (neg_dist[v] < nd) {
        neg_dist[v] = nd;
        que.push(make_pair(nd, v));
      }
    }
  }
  if (neg_dist[pair_to_int(dest)] <= NEG_DIST_MAX) {
    cout << "-1" << endl;
  } else {
    cout << -neg_dist[pair_to_int(dest)] << endl;
  }

  return 0;
}