Problem p00519 (C++) — buggy submission, verdict: Memory Limit Exceeded

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

vector<int> G[5000], H[5000];
int N, K;
int C[5000], R[5000];
int memo[5000];

unordered_set<int> bfs(int start) {
  unordered_set<int> res;
  struct Node {
    int vertex, distance;
  };
  queue<Node> q;
  q.push({start, 0});
  while (!q.empty()) {
    auto node = q.front();
    q.pop();
    if (R[start] < node.distance)
      break;
    if (res.count(node.vertex))
      continue;
    res.insert(node.vertex);
    for (const auto &v : G[node.vertex])
      if (!res.count(v))
        q.push({v, node.distance + 1});
  }
  return res;
}

int Dijkstra() {
  struct Node {
    int vertex, cost;
  };
  priority_queue<Node, vector<Node>, function<bool(Node, Node)>> q(
      [](Node lhs, Node rhs) {
        if (lhs.cost != rhs.cost)
          return lhs.cost > rhs.cost;
        return lhs.vertex < rhs.vertex;
      });
  set<int> visited;
  q.push({0, 0});
  while (!q.empty()) {
    auto node = q.top();
    q.pop();
    if (node.vertex == N - 1)
      return node.cost;
    if (visited.count(node.vertex))
      continue;
    visited.insert(node.vertex);
    for (const auto &v : H[node.vertex])
      if (!visited.count(v))
        if (node.cost + C[node.vertex] < memo[v])
          q.push({v, (memo[v] = node.cost + C[node.vertex])});
  }
  throw "NG";
}

int main() {
  cin >> N >> K;
  for (int i = 0; i < N; ++i) {
    cin >> C[i] >> R[i];
    memo[i] = INT_MAX;
  }

  for (int i = 0; i < K; ++i) {
    int A, B;
    cin >> A >> B;
    --A;
    --B;
    G[A].push_back(B);
    G[B].push_back(A);
  }

  for (int u = 0; u < N; ++u)
    for (const auto &v : bfs(u))
      H[u].push_back(v);
  cout << Dijkstra() << endl;
}

Error: MLE

Fixed submission:

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

vector<int> G[5000];
unordered_set<int> H[5000];
int N, K;
int C[5000], R[5000];
int memo[5000];

void bfs(int start) {
  struct Node {
    int vertex, distance;
  };
  queue<Node> q;
  q.push({start, 0});
  while (!q.empty()) {
    auto node = q.front();
    q.pop();
    if (R[start] < node.distance)
      break;
    if (H[start].count(node.vertex))
      continue;
    H[start].insert(node.vertex);
    for (const auto &v : G[node.vertex])
      if (!H[start].count(v))
        q.push({v, node.distance + 1});
  }
}

int Dijkstra() {
  struct Node {
    int vertex, cost;
  };
  priority_queue<Node, vector<Node>, function<bool(Node, Node)>> q(
      [](Node lhs, Node rhs) {
        if (lhs.cost != rhs.cost)
          return lhs.cost > rhs.cost;
        return lhs.vertex < rhs.vertex;
      });
  set<int> visited;
  q.push({0, 0});
  while (!q.empty()) {
    auto node = q.top();
    q.pop();
    if (node.vertex == N - 1)
      return node.cost;
    if (visited.count(node.vertex))
      continue;
    visited.insert(node.vertex);
    for (const auto &v : H[node.vertex])
      if (!visited.count(v))
        if (node.cost + C[node.vertex] < memo[v])
          q.push({v, (memo[v] = node.cost + C[node.vertex])});
  }
  throw "NG";
}

int main() {
  cin >> N >> K;
  for (int i = 0; i < N; ++i) {
    cin >> C[i] >> R[i];
    memo[i] = INT_MAX;
  }

  for (int i = 0; i < K; ++i) {
    int A, B;
    cin >> A >> B;
    --A;
    --B;
    G[A].push_back(B);
    G[B].push_back(A);
  }

  for (int u = 0; u < N; ++u)
    bfs(u);
  cout << Dijkstra() << endl;
}