## https://yukicoder.me/problems/no/2764 import heapq from collections import deque MAX_INT = 10 ** 18 def dijkstra(N, next_nodes, src): fix = [MAX_INT] * N seen = [MAX_INT] * N seen[src] = 0 queue = [] heapq.heappush(queue, (0, src)) while len(queue) > 0: cost, v = heapq.heappop(queue) if fix[v] < MAX_INT: continue fix[v] = cost for w, t in next_nodes[v]: if fix[w] < MAX_INT: continue new_cost = t + cost if seen[w] > new_cost: seen[w] = new_cost heapq.heappush(queue, (new_cost, w)) return fix def main(): N, M = map(int, input().split()) W = list(map(int, input().split())) next_nodes = [[] for _ in range(N)] for _ in range(M): u, v, t = map(int, input().split()) next_nodes[u - 1].append((v - 1, t)) next_nodes[v - 1].append((u - 1, t)) dists_from_s = dijkstra(N, next_nodes, 0) dists_from_t = dijkstra(N, next_nodes, N - 1) lines_w = {} for i in range(N): if dists_from_s[i] < MAX_INT: if W[i] not in lines_w: lines_w[W[i]] = dists_from_s[i] else: lines_w[W[i]] = min(lines_w[W[i]], dists_from_s[i]) lines = [(w, d) for w, d in lines_w.items()] lines.sort(key=lambda x : x[0], reverse=True) def compare(p1, p0): if p1[0] * p0[1] > p1[1] * p0[0]: return 1 elif p1[0] * p0[1] < p1[1] * p0[0]: return -1 else: return 0 # convex hull trick stack = deque() for w, d in lines: while len(stack) > 0: w0, d0, p0 = stack[-1] p1 = (d - d0, w0 - w) # p1 > p0 if compare(p1, p0) == 0: stack.pop() break elif compare(p1, p0) < 0: stack.pop() else: break if len(stack) == 0: stack.append((w, d, (0, 1))) else: stack.append((w, d, p1)) intervals = [] while len(stack) > 0: intervals.append(stack.popleft()) answer = dists_from_s[N - 1] for i in range(N): if dists_from_t[i] < MAX_INT: w = W[i] low = 0 high = len(intervals) - 1 while high - low > 1: mid = (high + low) // 2 if compare((w, 1), intervals[mid][2]) >= 0: low = mid else: high = mid if compare((w, 1), intervals[high][2]) >= 0: v = high else: v = low w0, d0, _ = intervals[v] ans = w * w0 + d0 + dists_from_t[i] answer = min(answer, ans) print(answer) if __name__ == "__main__": main()