JOI 2018 - Commuter Pass
Authors: Andi Qu, Nathan Wang
- Use Dijkstra's to calculate distances from , , and .
- Consider a subset of directed edges where each directed edge is part of a shortest path from to . Note that this subset is a DAG, and can be found by keeping track of the parents of every node when running Dijkstra's.
- Note that an optimal path will be , where is a path on the DAG. Note that any path on the DAG is a valid commuter pass option, and the only node with in-degree 0 is , and the only node with out-degree 0 is in the DAG.
- Define
dpU(i)
= minimum distance from to any node such that is in a path from to in the DAG. - Define
dpV(i)
= minimum distance from to any node such that is in a path from to in the DAG. - The DP transition for
dpU(i)
isdpU(i) = min(distU[i], dpU(parent_i))
for each parent ofi
(seedijkstra2
function implementation for more details).dpV
's transition is defined similarly. - Our answer is
dpU(v) + dpV(v)
. Since edges are bidirectional, an optimal path can also be where is a path on the DAG. We can solve this by rerunning steps 2-7 while switching and . In Andi's code, steps 2-7 are implemented in thedijkstra2
function. - Alternatively, the answer could just be from directly to without using the commuter pass.
Code
Andi's implementation:
1#include <bits/stdc++.h>2typedef long long ll;3using namespace std;45vector<pair<ll, ll>> graph[100001];6ll du[100001], dv[100001], ds[100001], dp[2][100001], ans;7bool visited[100001];89void dijkstra1(ll start, ll arr[]) {10 fill(visited, visited + 100001, false);
Alternatively, Nathan's implementation. Note that the DP definitions in Nathan's implementation are slightly different than above.
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!