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

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

using ll = long long;
using pii = pair<int, int>;

template <typename T> constexpr T inf;
template <> constexpr int inf<int> = 1e9;
template <> constexpr ll inf<ll> = 1e18;
template <> constexpr double inf<double> = 1e18;

template <typename T> std::vector<T> table(int n, T v) {
  return std::vector<T>(n, v);
}

template <class... Args> auto table(int n, Args... args) {
  auto val = table(args...);
  return std::vector<decltype(val)>(n, std::move(val));
}

struct edge {
  int to;
  ll cost;
  int id;
};

using edges = vector<edge>;
using graph = vector<edges>;

void add_edge(graph &g, int u, int v, ll cost, int id) {
  g[u].push_back(edge{v, cost, id});
  g[v].push_back(edge{u, cost, id});
}

struct node {
  int v, pre;
  ll dist;

  node(int v, ll dist, int prev) : v(v), pre(prev), dist(dist) {}

  bool operator<(const node &other) const { return dist > other.dist; }
};

int main() {
  int N, M, s, t;
  scanf("%d %d %d %d", &N, &M, &s, &t);
  s--, t--;

  graph g(N);
  for (int i = 0; i < M; ++i) {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    a--;
    b--;
    c--;

    add_edge(g, a, b, d, i);
    add_edge(g, b, c, d, i);
    add_edge(g, c, a, d, i);
  }

  priority_queue<node> que;
  vector<unordered_map<int, ll>> d(N);
  vector<ll> min_d(N, 1e18);
  que.emplace(s, 0, -1);
  d[s][-1] = 0;
  min_d[s] = 0;

  ll ans = 0;
  while (!que.empty()) {
    auto now = que.top();
    que.pop();
    if (min_d[now.v] < now.dist)
      continue;
    if (now.v == t) {
      ans = now.dist;
      break;
    }
    for (const auto &e : g[now.v]) {
      if (min_d[e.to] > now.dist + e.cost &&
          (d[e.to].count(e.id) == 0 ||
           (d[e.to].count(e.id) == 1 && d[e.to][e.id] > now.dist + e.cost))) {
        d[e.to][e.id] = now.dist + e.cost;
        que.emplace(e.to, d[e.to][e.id], e.id);
        min_d[e.to] = now.dist + e.cost;
      }
    }
  }
  cout << ans << endl;
}

// ll solve(ll n) {
//     const auto s = to_string(n);
//     const int m = s.size();
//     // [pos][i - 3][i - 2][i - 1][already ok][strictly less]
//     auto dp = table<ll>(m + 1, 10, 10, 10, 2, 2, 0);
//     dp[0][0][0][0][0][0] = 1;
//     for(int i = 0; i < m; ++i) {
//         for(int i3 = 0; i3 <= 9; ++i3) for(int i2 = 0; i2 <= 9; ++i2) for(int
//         i1 = 0; i1 <= 9; ++i1) {
//             for(int aok = 0; aok <= 1; ++aok) {
//                 for(int le = 0; le <= 1; ++le) {
//                     const int lim = le ? 9 : s[i] - '0';
//                     for(int add = 0; add <= lim; ++add) {
//                         int nok = aok || (i3 == 5 && i2 == 1 && add == 3);
//                         int nle = le || s[i] - '0' > add;
//                         dp[i + 1][i2][i1][add][nok][nle] +=
//                         dp[i][i3][i2][i1][aok][le];
//                     }
//                 }
//             }
//         }
//     }
//
//     ll ans = 0;
//     for(int i = 0; i <= 9; ++i) {
//         for(int j = 0; j <= 9; ++j) {
//             for(int k = 0; k <= 9; ++k) {
//                 ans += dp[m][i][j][k][1][0] + dp[m][i][j][k][1][1];
//             }
//         }
//     }
//     return ans;
// }

// int main() {
//     ll N;
//     cin >> N;
//     cout << solve(N) << endl;
// }


Error: TLE

Fixed submission:

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

using ll = long long;
using pii = pair<int, int>;

template <typename T> constexpr T inf;
template <> constexpr int inf<int> = 1e9;
template <> constexpr ll inf<ll> = 1e18;
template <> constexpr double inf<double> = 1e18;

template <typename T> std::vector<T> table(int n, T v) {
  return std::vector<T>(n, v);
}

template <class... Args> auto table(int n, Args... args) {
  auto val = table(args...);
  return std::vector<decltype(val)>(n, std::move(val));
}

struct edge {
  int to;
  ll cost;
  int id;
};

using edges = vector<edge>;
using graph = vector<edges>;

void add_edge(graph &g, int u, int v, ll cost, int id) {
  g[u].push_back(edge{v, cost, id});
  g[v].push_back(edge{u, cost, id});
}

struct node {
  int v, pre;
  ll dist;

  node(int v, ll dist, int prev) : v(v), pre(prev), dist(dist) {}

  bool operator<(const node &other) const { return dist > other.dist; }
};

int main() {
  int N, M, s, t;
  scanf("%d %d %d %d", &N, &M, &s, &t);
  s--, t--;

  graph g(N);
  for (int i = 0; i < M; ++i) {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    a--;
    b--;
    c--;

    add_edge(g, a, b, d, i);
    add_edge(g, b, c, d, i);
    add_edge(g, c, a, d, i);
  }

  priority_queue<node> que;
  vector<unordered_map<int, ll>> d(N);
  vector<ll> min_d(N, 1e18);
  que.emplace(s, 0, -1);
  d[s][-1] = 0;
  min_d[s] = 0;

  ll ans = 0;
  while (!que.empty()) {
    auto now = que.top();
    que.pop();
    if (min_d[now.v] < now.dist)
      continue;
    if (now.v == t) {
      ans = now.dist;
      break;
    }
    for (const auto &e : g[now.v]) {
      if (min_d[e.to] > now.dist + e.cost &&
          (d[e.to].count(e.id) == 0 ||
           (d[e.to].count(e.id) == 1 && d[e.to][e.id] > now.dist + e.cost))) {
        d[e.to][e.id] = now.dist + e.cost;
        que.emplace(e.to, d[e.to][e.id], e.id);
      }
    }
  }
  cout << ans << endl;
}

// ll solve(ll n) {
//     const auto s = to_string(n);
//     const int m = s.size();
//     // [pos][i - 3][i - 2][i - 1][already ok][strictly less]
//     auto dp = table<ll>(m + 1, 10, 10, 10, 2, 2, 0);
//     dp[0][0][0][0][0][0] = 1;
//     for(int i = 0; i < m; ++i) {
//         for(int i3 = 0; i3 <= 9; ++i3) for(int i2 = 0; i2 <= 9; ++i2) for(int
//         i1 = 0; i1 <= 9; ++i1) {
//             for(int aok = 0; aok <= 1; ++aok) {
//                 for(int le = 0; le <= 1; ++le) {
//                     const int lim = le ? 9 : s[i] - '0';
//                     for(int add = 0; add <= lim; ++add) {
//                         int nok = aok || (i3 == 5 && i2 == 1 && add == 3);
//                         int nle = le || s[i] - '0' > add;
//                         dp[i + 1][i2][i1][add][nok][nle] +=
//                         dp[i][i3][i2][i1][aok][le];
//                     }
//                 }
//             }
//         }
//     }
//
//     ll ans = 0;
//     for(int i = 0; i <= 9; ++i) {
//         for(int j = 0; j <= 9; ++j) {
//             for(int k = 0; k <= 9; ++k) {
//                 ans += dp[m][i][j][k][1][0] + dp[m][i][j][k][1][1];
//             }
//         }
//     }
//     return ans;
// }

// int main() {
//     ll N;
//     cin >> N;
//     cout << solve(N) << endl;
// }