module main; // https://yang33-kassa.jp/yukicoder/yukicoder001/ より // 拡張ダイクストラ法 import std; int N, C, V; int[] S, T, Y, M; immutable INF = int.max / 2; alias P = Tuple!(int, int, int); // C++ の tie auto tie(StoreElements...)(ref StoreElements stores) { alias Elements = staticMap!(Unqual, StoreElements); template toPointer(T) { alias toPointer = T*; } struct Holder { alias StoreElementsPtrs = staticMap!(toPointer, StoreElements); StoreElementsPtrs storePtrs; this(ref StoreElements stores) { foreach(i, _; StoreElements) { storePtrs[i] = &stores[i]; } } void opAssign(Tuple!Elements values) { foreach(i, _; Elements) { *storePtrs[i] = values[i]; } } } return Holder(stores); } void main() { // 入力 N = readln.chomp.to!int; C = readln.chomp.to!int; V = readln.chomp.to!int; S = readln.split.to!(int[]); --S[]; T = readln.split.to!(int[]); --T[]; Y = readln.split.to!(int[]); M = readln.split.to!(int[]); // 答えの計算 auto G = new P[][](N); foreach (i; 0 .. V) G[S[i]] ~= P(T[i], Y[i], M[i]); auto dist = new int[][](N, C + 1); foreach (ref d; dist) d[] = INF; dist[0][0] = 0; auto pq = redBlackTree(P(0, 0, 0)); while (!pq.empty) { P a = pq.front; pq.removeFront; int d, c, v; tie(d, c, v) = a; if (dist[v][c] < d) continue; foreach (i; 0 .. G[v].length.to!int) { int nv, adc, adt; // 行先の町、コスト、かかる時間 tie(nv, adc, adt) = G[v][i]; if (adc + c > C) continue; if (dist[nv][adc + c] > dist[v][c] + adt) { dist[nv][adc + c] = dist[v][c] + adt; pq.insert(P(dist[nv][adc + c], adc + c, nv)); } } } // 答えの出力 int ans = dist[N - 1].minElement; writeln(ans == INF ? -1 : ans); }