#include 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 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 struct StaticGraph { private: template 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>> es; vector start; vector> 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){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){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){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){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>::iterator> operator[](int v) { assert(built); assert(0 <= v && v < n); return {eli.begin() + start[v], eli.begin() + start[v + 1]}; } }; namespace dijkstra { template vector Dijkstra(StaticGraph &g, int s) { T mx = (is_same::value ? 2000000000 : 1000000000000000000); vector d(g.size(), mx); priority_queue, vector>, greater>> 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 struct DijkstraRestore { private: int s; T mx; vector d; vector> prev; priority_queue, vector>, greater>> pq; public: DijkstraRestore() {} DijkstraRestore(StaticGraph &g, int s_) : s(s_), prev(g.size()) { mx = (is_same::value ? 2000000000 : 1000000000000000000); d.resize(g.size(), mx); priority_queue, vector>, greater>> 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 dists() const { return d; } T dist(int t) const { assert(0 <= t && t < (int)d.size()); return d[t]; } vector> route(int t) const { assert(0 <= t && t < (int)d.size()); if (s == t || d[t] == mx) { return {}; } vector> 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 c(m); rep(i, m) { cin >> c[i]; } StaticGraph 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"; }