結果
問題 |
No.3111 Toll Optimization
|
ユーザー |
![]() |
提出日時 | 2025-04-19 11:31:26 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 253 ms / 5,000 ms |
コード長 | 5,938 bytes |
コンパイル時間 | 4,791 ms |
コンパイル使用メモリ | 289,852 KB |
実行使用メモリ | 88,664 KB |
最終ジャッジ日時 | 2025-04-19 11:31:42 |
合計ジャッジ時間 | 13,486 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 70 |
ソースコード
#include <bits/stdc++.h> using namespace std; #define For(i, a, b) for(int i = (a); i < (b); i++) #define rep(i, n) For(i, 0, n) #define rFor(i, a, b) for(int i = (a); i >= (b); i--) #define ALL(v) (v).begin(), (v).end() #define rALL(v) (v).rbegin(), (v).rend() #define SZ(v) ((int)(v).size()) using lint = long long; using ld = long double; int INF = 2000000000; lint LINF = 1000000000000000000; struct SetupIo { SetupIo() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(15); cerr << fixed << setprecision(15); } } setupio; template <class T> struct Edge { int from, to; T cost; int idx; Edge() {} Edge(int to_) : to(to_) {} Edge(int to_, T cost_) : to(to_), cost(cost_) {} Edge(int from_, int to_, int idx_) : from(from_), to(to_), idx(idx_) {} Edge(int from_, int to_, T cost_, int idx_) : from(from_), to(to_), cost(cost_), idx(idx_) {} }; template <class T> struct StaticGraph { private: template <class It> struct Es { It b, e; It begin() const { return b; } It end() const { return e; } int size() const { return int(e - b); } auto &&operator[](int i) const { return b[i]; } }; int n; vector<pair<int, Edge<T>>> es; vector<int> start; vector<Edge<T>> eli; bool built; public: StaticGraph() {} StaticGraph(int n_) : n(n_), start(n + 1), built(false) {} void add(int u, int v) { assert(!built); assert(0 <= u && u < n); assert(0 <= v && v < n); es.emplace_back(u, (Edge<T>){v}); } void add(int u, int v, T w) { assert(!built); assert(0 <= u && u < n); assert(0 <= v && v < n); es.emplace_back(u, (Edge<T>){v, w}); } void add(int u, int u_, int v, int i) { assert(!built); assert(0 <= u && u < n); assert(u == u_); assert(0 <= v && v < n); es.emplace_back(u, (Edge<T>){u, v, i}); } void add(int u, int u_, int v, T w, int i) { assert(!built); assert(0 <= u && u < n); assert(0 <= v && v < n); assert(u == u_); es.emplace_back(u, (Edge<T>){u, v, w, i}); } void build() { if (built) { return; } eli.resize(es.size()); for (auto [v, e] : es) { start[v + 1]++; } for (int i = 1; i <= n; i++) { start[i] += start[i - 1]; } auto counter = start; for (auto [v, e] : es) { eli[counter[v]++] = e; } built = true; } int size() const { return n; } Es<typename vector<Edge<T>>::iterator> operator[](int v) { assert(built); assert(0 <= v && v < n); return {eli.begin() + start[v], eli.begin() + start[v + 1]}; } }; namespace dijkstra { template <class T> vector<T> Dijkstra(StaticGraph<T> &g, int s) { T mx = (is_same<T, int>::value ? 2000000000 : 1000000000000000000); vector<T> d(g.size(), mx); priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> pq; d[s] = T(0); pq.emplace(d[s], s); while (!pq.empty()) { auto [c, v] = pq.top(); pq.pop(); if (d[v] < c) { continue; } for (auto &e : g[v]) { int nv = e.to; T nc = c + e.cost; if (d[nv] > nc) { d[nv] = nc; pq.emplace(d[nv], nv); } } } return d; } template <class T> struct DijkstraRestore { private: int s; T mx; vector<T> d; vector<Edge<T>> prev; priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> pq; public: DijkstraRestore() {} DijkstraRestore(StaticGraph<T> &g, int s_) : s(s_), prev(g.size()) { mx = (is_same<T, int>::value ? 2000000000 : 1000000000000000000); d.resize(g.size(), mx); priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> pq; d[s] = T(0); pq.emplace(d[s], s); while (!pq.empty()) { auto [c, v] = pq.top(); pq.pop(); if (d[v] < c) { continue; } for (auto &e : g[v]) { int nv = e.to; T nc = c + e.cost; if (d[nv] > nc) { d[nv] = nc; prev[nv] = e; pq.emplace(d[nv], nv); } } } } vector<T> dists() const { return d; } T dist(int t) const { assert(0 <= t && t < (int)d.size()); return d[t]; } vector<Edge<T>> route(int t) const { assert(0 <= t && t < (int)d.size()); if (s == t || d[t] == mx) { return {}; } vector<Edge<T>> res; int cur = t; while (cur != s) { res.emplace_back(prev[cur]); cur = prev[cur].from; } reverse(res.begin(), res.end()); return res; } }; } // namespace dijkstra using namespace dijkstra; int main() { int n, m, k; cin >> n >> m >> k; vector<lint> c(m); rep(i, m) { cin >> c[i]; } StaticGraph<lint> g((k + 1) * n); rep(i, m) { int u, v; cin >> u >> v; u--, v--; rep(j, k + 1) { int x = u + j * n; int y = v + j * n; g.add(x, y, c[i]); g.add(y, x, c[i]); } rep(j, k) { g.add(u + j * n, v + (j + 1) * n, 0LL); g.add(v + j * n, u + (j + 1) * n, 0LL); } } g.build(); auto d = Dijkstra(g, 0); lint ans = LINF; rep(i, k + 1) { ans = min(ans, d[(n - 1) + i * n]); } cout << (ans != LINF ? ans : -1) << "\n"; }