JOI 2018 - Commuter Pass

Authors: Andi Qu, Nathan Wang

Table of Contents

Code
Edit on Github
  1. Use Dijkstra's to calculate distances from , , and .
  2. 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.
  3. 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.
  4. Define dpU(i) = minimum distance from to any node such that is in a path from to in the DAG.
  5. Define dpV(i) = minimum distance from to any node such that is in a path from to in the DAG.
  6. The DP transition for dpU(i) is dpU(i) = min(distU[i], dpU(parent_i)) for each parent of i (see dijkstra2 function implementation for more details). dpV's transition is defined similarly.
  7. 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 the dijkstra2 function.
  8. 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;
4
5vector<pair<ll, ll>> graph[100001];
6ll du[100001], dv[100001], ds[100001], dp[2][100001], ans;
7bool visited[100001];
8
9void 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!

Give Us Feedback on JOI 2018 - Commuter Pass!