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

#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
#include <utility>
#include <vector>

struct Edge {
  size_t from, to, distance, attack;
};

struct Info {
  size_t attacks, place, money;

  friend bool operator>(Info const &lhs, Info const &rhs) {
    if (lhs.attacks != rhs.attacks) {
      return lhs.attacks > rhs.attacks;
    }
    if (lhs.money != rhs.money) {
      return lhs.money < rhs.money;
    }
    return lhs.place > rhs.place;
  }
};

size_t solve(size_t N, size_t M, size_t L) {
  std::vector<std::vector<Edge>> adj_list(N);
  for (size_t i = 0; i < M; i++) {
    size_t f, t, d, e;
    std::cin >> f >> t >> d >> e;
    adj_list[f - 1].push_back(Edge{f - 1, t - 1, d, e});
    adj_list[t - 1].push_back(Edge{t - 1, f - 1, d, e});
  }

  std::priority_queue<Info, std::vector<Info>, std::greater<Info>> queue;
  // ??°???n??????????????????????°?attack
  std::vector<std::vector<size_t>> min_attacks(
      N, std::vector<size_t>(L + 1, 2 << 29));
  min_attacks[0][L] = 0;
  queue.push(Info{0, 0, L});
  while (!queue.empty()) {
    auto info = queue.top();
    queue.pop();
    // std::cout << "info " << info.attacks << " " << info.place << " " <<
    // info.money << std::endl;
    if (min_attacks[info.place][info.money] < info.attacks) {
      continue;
    }
    for (auto const &edge : adj_list[info.place]) {
      if (edge.distance <= info.money) {
        if (info.attacks < min_attacks[edge.to][info.money - edge.distance]) {
          min_attacks[edge.to][info.money - edge.distance] = info.attacks;
          queue.push(Info{info.attacks, edge.to, info.money - edge.distance});
        }
      }
      if (info.attacks + edge.attack < min_attacks[edge.to][info.money]) {
        min_attacks[edge.to][info.money] = info.attacks + edge.attack;
        queue.push(Info{info.attacks + edge.attack, edge.to, info.money});
      }
    }
  }
  size_t min_attack = 2 << 29;
  for (auto const &attacks : min_attacks[N - 1]) {
    if (min_attack > attacks) {
      min_attack = attacks;
    }
  }
  return min_attack;
}

int main() {
  size_t N, M, L;
  while (std::cin >> N >> M >> L) {
    if (N == 0 && M == 0 && L == 0) {
      break;
    }
    std::cout << solve(N, M, L) << std::endl;
  }
}

Error: MLE

Fixed submission:

#include <cassert>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
#include <utility>
#include <vector>

struct Edge {
  int from, to, distance, attack;
};

struct Info {
  int attacks, place, money;

  friend bool operator>(Info const &lhs, Info const &rhs) {
    if (lhs.attacks != rhs.attacks) {
      return lhs.attacks > rhs.attacks;
    }
    if (lhs.money != rhs.money) {
      return lhs.money < rhs.money;
    }
    return lhs.place > rhs.place;
  }

  friend bool operator<(Info const &lhs, Info const &rhs) {
    return !(lhs > rhs);
  }
};

int solve(int N, int M, int L) {
  std::vector<std::vector<Edge>> adj_list(N);
  for (int i = 0; i < M; i++) {
    int f, t, d, e;
    std::cin >> f >> t >> d >> e;
    adj_list[f - 1].push_back(Edge{f - 1, t - 1, d, e});
    adj_list[t - 1].push_back(Edge{t - 1, f - 1, d, e});
  }

  std::priority_queue<Info, std::vector<Info>, std::greater<Info>> queue;
  std::set<Info> visited;
  queue.push(Info{0, 0, L});
  while (!queue.empty()) {
    auto info = queue.top();
    queue.pop();
    if (visited.find(info) != visited.end()) {
      continue;
    }
    visited.insert(info);
    // std::cout << "info: " << info.attacks << " " << info.place << " " <<
    // info.money << std::endl;
    if (info.place == N - 1) {
      return info.attacks;
    }
    for (auto const &edge : adj_list[info.place]) {
      if (edge.distance <= info.money) {
        // std::cout << "pushing: " << info.attacks << " " << edge.to << " " <<
        // info.money - edge.distance << std::endl;
        queue.push(Info{info.attacks, edge.to, info.money - edge.distance});
      }
      // std::cout << "pushing: " << info.attacks + edge.attack << " " <<
      // edge.to << " " << info.money << std::endl;
      queue.push(Info{info.attacks + edge.attack, edge.to, info.money});
    }
  }
  assert(false);
}

int main() {
  int N, M, L;
  while (std::cin >> N >> M >> L) {
    if (N == 0 && M == 0 && L == 0) {
      break;
    }
    std::cout << solve(N, M, L) << std::endl;
  }
}