Do we need weird dijkstra to solve this JOI problems? 
Difference between en1 and en2, changed 6 character(s)
Hi Codeforces! ↵
Commuter Pass ( JOI 2017 — 2018 ) : https://oj.uz/problem/view/JOI18_commuter_pass↵
Now, I will summarize the problem statement:  ↵
Given a weighted graph with n vertices and m edges, along with four specific vertices s, t, u, v. We can choose a shortest path from s to t to travel for free. The problem requires us to minimize the travel cost between u and v assuming we optimally select the free path from s to t. We can easily see that the optimal result is the minimum of the direct distance between u and v and the sum of the distance from u to the nearest vertex on the free path from s to t and the distance from v to the nearest vertex on the free path from s to t.  ↵

I couldn't solve this problem using a standard Dijkstra algorithm, even though I found the solution (which is also the main approach to solving the problem). However, in the author's sample code, they used a rather unusual variation of Dijkstra. Everything else is implemented as in the standard solution. Can anybody explain me why? ↵

```cpp↵
void dijkstra1(ll start, ll arr[]) {↵
fill(visited, visited + 100001, false);↵

priority_queue<pair<ll, ll>> pq;↵
pq.push({0, start});↵
while (!pq.empty()) {↵
ll c, node;↵
tie(c, node) = pq.top();↵
pq.pop();↵

if (!visited[node]) {↵
arr[node] = -c;↵
visited[node] = true;↵
for (auto &i : graph[node]) pq.push({c - i.second, i.first});↵
}↵
}↵
}↵

void dijkstra2(ll start, ll end) {↵
fill(dp[0], dp[0] + 100001, LLONG_MAX / 2);↵
fill(dp[1], dp[1] + 100001, LLONG_MAX / 2);↵
fill(visited, visited + 100001, false);↵

priority_queue<pair<ll, pair<ll, ll>>> pq;↵
pq.push({0, {start, 0}});↵
dp[0][0] = dp[1][0] = LLONG_MAX / 2;↵
while (!pq.empty()) {↵
ll c, node, par;↵
pair<ll, ll> p;↵
tie(c, p) = pq.top();↵
tie(node, par) = p;↵
pq.pop();↵

if (!visited[node]) {↵
visited[node] = true;↵
ds[node] = -c;↵
dp[0][node] = min(du[node], dp[0][par]);↵
dp[1][node] = min(dv[node], dp[1][par]);↵
for (auto i : graph[node]) pq.push({c - i.second, {i.first, node}});↵
} else if (-c == ds[node]) {↵
if (min(du[node], dp[0][par]) + min(dv[node], dp[1][par]) <=↵
    dp[0][node] + dp[1][node]) {↵
dp[0][node] = min(du[node], dp[0][par]);↵
dp[1][node] = min(dv[node], dp[1][par]);↵
}↵
}↵
}↵

ans = min(ans, dp[0][end] + dp[1][end]);↵
} ↵
```

Author 's Code : https://usaco.guide/problems/joi-2018commuter-pass/solution↵

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en2 English thaonguyendethuongvai 2025-02-03 17:18:04 6
en1 English thaonguyendethuongvai 2025-02-03 17:17:25 2493 Initial revision (published)