Editorial for Just One More Tunnel (Easy)
Submitting an official solution before solving the problem yourself is a bannable offence.
Every corridor and tunnel has nonnegative cost. Removing a cycle from a walk therefore cannot increase its cost, even when the cycle costs zero. Consequently, a shortest walk always has a simple path of the same or lower cost. We can use Dijkstra's algorithm without tracking which rooms have been visited along each candidate route.
Representing the Tunnels
Adding a tunnel between every pair of shortcut rooms would create up to edges. Instead, introduce one auxiliary vertex
. For each shortcut room
, add two directed edges:
with cost
;
with cost
.
Keep each ordinary corridor as two directed edges of its original cost. Moving from one shortcut room to another through costs exactly
in either direction. In particular, the tunnel cost must be charged only once, not on both edges.
Run Dijkstra from room . Print the distance to room
, or
Impossible if it is unreachable.
Correctness
Every valid route in the original graph gives a walk of the same cost in the auxiliary graph: replace each tunnel by its two edges through . Thus the shortest auxiliary distance cannot exceed the optimal route cost.
Conversely, take a shortest auxiliary walk. Every passage through has the form
for shortcut rooms
and
. When
, replace it by the corresponding tunnel. When
, discard the excursion; its cost is nonnegative. This gives a walk in the original graph of no greater cost. Remove repeated-vertex cycles to obtain a simple route, again without increasing the cost.
The two inequalities show that the shortest auxiliary distance is exactly the required answer. The same construction preserves reachability, so an unreachable finish is correctly reported as Impossible.
Complexity
The auxiliary graph has vertices and at most
directed edges. Dijkstra with a binary heap takes
time and
memory. A 64-bit distance type and a sufficiently large infinity value are convenient.
The included sol.cpp also handles negative tunnel times using min-cost flow. It remains correct for this version, but the simpler Dijkstra solution above is sufficient.
Comments