#include #include #include #include using namespace std; // SPFA修正版 (多分ダイクストラより早い) struct Edge { int to; unsigned long long w; }; const unsigned long long INF = ~0ULL; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, M; if (!(cin >> N >> M)) return 0; vector> adj(N + 1); for (int i = 0; i < M; ++i) { int u, v; unsigned long long w; cin >> u >> v >> w; adj[u].push_back({v, w}); adj[v].push_back({u, w}); } vector A(N + 1), B(N + 1), C(N + 1); for (int i = 1; i <= N; ++i) cin >> A[i]; for (int i = 1; i <= N; ++i) cin >> B[i]; for (int i = 1; i <= N; ++i) cin >> C[i]; vector dist(N + 1, INF); vector in_queue(N + 1, false); queue q; dist[1] = 0; q.push(1); in_queue[1] = true; while (!q.empty()) { int u = q.front(); q.pop(); in_queue[u] = false; for (const auto& edge : adj[u]) { int v = edge.to; unsigned long long w = edge.w; unsigned long long k0 = (dist[u] + A[u] - 1) / A[u]; if (k0 < 1) k0 = 1; unsigned long long min_arrival = INF; // 直近の便(k0) と 1本見送った便(k0 + 1) の短い方を採用 for (unsigned long long k = k0; k <= k0 + 1; ++k) { unsigned long long dept = k * A[u]; unsigned long long cost = w; if (k % B[u] == 0) { cost += C[u]; } min_arrival = min(min_arrival, dept + cost); } if (min_arrival < dist[v]) { dist[v] = min_arrival; if (!in_queue[v]) { q.push(v); in_queue[v] = true; } } } } cout << dist[N] << "\n"; return 0; }