Initialize dist[1][0] = 0 (you start at city with no discount used) and all other distances to infinity. Push (0, 1, 0) onto the heap. Pop (cost, u, used). If cost > dist[u][used], skip (already found better). Otherwise, for each neighbor v with edge cost w, consider two transitions:
Take edge normally: if cost + w < dist[v][used], update and push (cost + w, v, used).
If used == 0, apply discount: if cost + w // 2 < dist[v][1], update and push (cost + w // 2, v, 1). The answer is min(dist[n][0], dist[n][1]).
This runs in time and uses space.