Problem p01919 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;
using ll = long long;

#define all(c) (c).begin(), (c).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define pb(e) push_back(e)
#define mp(a, b) make_pair(a, b)
#define fr first
#define sc second

const ll INF = 1e18;
const ll MOD = 1e9 + 7;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

template <typename T> inline size_t hashCombine(size_t seed, const T &v) {
  return seed ^ (hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}

namespace std {
template <typename T, typename S> class hash<pair<T, S>> {
public:
  size_t operator()(const pair<T, S> &p) const {
    size_t seed = 0;
    seed = hashCombine(seed, p.first);
    seed = hashCombine(seed, p.second);
    return seed;
  }
};
template <typename... Ts> class hash<tuple<Ts...>> {
public:
  size_t operator()(const tuple<Ts...> &t) const { return impl<0>(t); }

private:
  template <size_t Index>
  typename enable_if<Index == tuple_size<tuple<Ts...>>::value, size_t>::type
  impl(const tuple<Ts...> &) const {
    return 0;
  }
  template <size_t Index>
  typename enable_if<Index != tuple_size<tuple<Ts...>>::value, size_t>::type
  impl(const tuple<Ts...> &t) const {
    return hashCombine(impl<Index + 1>(t), get<Index>(t));
  }
};
} // namespace std

int n, m;
int a, b, c;
int v0;
struct Edge {
  int to, t;
  Edge(int to = 0, int t = 0) : to(to), t(t) {}
};
int update(int v) { return (a * v + b) % c; }
vector<Edge> G[502];
using State = tuple<int, int, int>;
unordered_map<State, ll> dp;
priority_queue<pair<ll, State>> que;

int main() {
  cin >> n >> m;
  rep(i, m) {
    int x, y, t;
    cin >> x >> y >> t;
    G[x].push_back(Edge(y, t));
    G[y].push_back(Edge(x, t));
  }
  cin >> v0;
  cin >> a >> b >> c;
  auto initState = State(1, v0, 0);
  dp[initState] = 0;
  que.push(make_pair(0, initState));

  while (que.size()) {
    auto p = que.top();
    que.pop();
    auto nowCost = p.first;
    auto nowState = p.second;
    auto v = get<0>(nowState);
    auto v1 = get<1>(nowState);
    auto s = get<2>(nowState);
    auto v2 = update(v1);
    // printf("%d %d %d %d\n", v, v1, s, dp[nowState]);

    if (s == 0 && v == n)
      s = 1;
    rep(i, G[v].size()) {
      auto e = G[v][i];
      ll cost = 1LL * e.t * v1;
      auto nextState = State(e.to, v2, s);
      if (dp.count(nextState) == 0 || dp[nowState] + cost < dp[nextState]) {
        dp[nextState] = dp[nowState] + cost;
        que.push(make_pair(-dp[nextState], nextState));
      }
    }
  }

  ll ans = INF;
  rep(i, 50) {
    auto s = State(1, i, 1);
    if (dp.count(s))
      ans = min(ans, dp[s]);
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;
using ll = long long;

#define all(c) (c).begin(), (c).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define pb(e) push_back(e)
#define mp(a, b) make_pair(a, b)
#define fr first
#define sc second

const ll INF = 1e18;
const ll MOD = 1e9 + 7;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

template <typename T> inline size_t hashCombine(size_t seed, const T &v) {
  return seed ^ (hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}

namespace std {
template <typename T, typename S> class hash<pair<T, S>> {
public:
  size_t operator()(const pair<T, S> &p) const {
    size_t seed = 0;
    seed = hashCombine(seed, p.first);
    seed = hashCombine(seed, p.second);
    return seed;
  }
};
template <typename... Ts> class hash<tuple<Ts...>> {
public:
  size_t operator()(const tuple<Ts...> &t) const { return impl<0>(t); }

private:
  template <size_t Index>
  typename enable_if<Index == tuple_size<tuple<Ts...>>::value, size_t>::type
  impl(const tuple<Ts...> &) const {
    return 0;
  }
  template <size_t Index>
  typename enable_if<Index != tuple_size<tuple<Ts...>>::value, size_t>::type
  impl(const tuple<Ts...> &t) const {
    return hashCombine(impl<Index + 1>(t), get<Index>(t));
  }
};
} // namespace std

int n, m;
int a, b, c;
int v0;
struct Edge {
  int to, t;
  Edge(int to = 0, int t = 0) : to(to), t(t) {}
};
int update(int v) { return (a * v + b) % c; }
vector<Edge> G[502];
using State = tuple<int, int, int>;
unordered_map<State, ll> dp;
priority_queue<pair<ll, State>> que;

int main() {
  cin >> n >> m;
  rep(i, m) {
    int x, y, t;
    cin >> x >> y >> t;
    G[x].push_back(Edge(y, t));
    G[y].push_back(Edge(x, t));
  }
  cin >> v0;
  cin >> a >> b >> c;
  auto initState = State(1, v0, 0);
  dp[initState] = 0;
  que.push(make_pair(0, initState));

  while (que.size()) {
    auto p = que.top();
    que.pop();
    auto nowCost = p.first;
    auto nowState = p.second;
    auto v = get<0>(nowState);
    auto v1 = get<1>(nowState);
    auto s = get<2>(nowState);
    auto v2 = update(v1);
    if (dp[nowState] < -nowCost)
      continue;
    // printf("%d %d %d %d\n", v, v1, s, dp[nowState]);

    if (s == 0 && v == n)
      s = 1;
    rep(i, G[v].size()) {
      auto e = G[v][i];
      ll cost = 1LL * e.t * v1;
      auto nextState = State(e.to, v2, s);
      if (dp.count(nextState) == 0 || dp[nowState] + cost < dp[nextState]) {
        dp[nextState] = dp[nowState] + cost;
        que.push(make_pair(-dp[nextState], nextState));
      }
    }
  }

  ll ans = INF;
  rep(i, 50) {
    auto s = State(1, i, 1);
    if (dp.count(s))
      ans = min(ans, dp[s]);
  }
  cout << ans << endl;
  return 0;
}