Do we need weird dijkstra to solve this JOI problems?

Правка en2, от thaonguyendethuongvai, 2025-02-03 17:18:04

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

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en2 Английский thaonguyendethuongvai 2025-02-03 17:18:04 6
en1 Английский thaonguyendethuongvai 2025-02-03 17:17:25 2493 Initial revision (published)