Submission #1348339

#TimeUsernameProblemLanguageResultExecution timeMemory
1348339msb.83Currents (EGOI25_currents)C++20
100 / 100
225 ms27268 KiB
#pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int INF = 1e9 + 7;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n, m;
    if (!(cin >> n >> m)) return 0;

    vector<vector<int>> adj(n);
    vector<vector<int>> adjr(n);

    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adjr[v].push_back(u);
    }

    // 1. BFS from 0 to all nodes in the original graph.
    // This gives us the cost to reach 0 if the troll flips the graph while we are at cave u.
    // Do NOT skip cave n-1, because after a flip, n-1 is just a normal cave!
    vector<int> dist0(n, INF);
    queue<int> q;
    dist0[0] = 0;
    q.push(0);

    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v : adj[u]) {
            if (dist0[v] == INF) {
                dist0[v] = dist0[u] + 1;
                q.push(v);
            }
        }
    }

    // 2. Min-Max Dijkstra starting from the exit N-1 backwards.
    vector<int> res(n, INF);
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

    res[n - 1] = 0;
    pq.push({0, n - 1});

    while (!pq.empty()) {
        int d = pq.top().first;
        int u = pq.top().second;
        pq.pop();

        // Standard Dijkstra optimization to skip outdated distance pairs
        if (d > res[u]) continue;

        for (int v : adjr[u]) {
            // If I am at v, and decide to move to u:
            // Troll can flip NOW: Cost is dist0[v]
            // Troll waits: Cost is 1 move (to u) + whatever the worst-case cost from u is (res[u])
            // The troll chooses the max of these. 
            // We want to minimize our time, so we only update if this path is better than our current res[v].
            int weight = max(dist0[v], res[u] + 1);
            
            if (weight < res[v]) {
                res[v] = weight;
                pq.push({res[v], v});
            }
        }
    }

    // 3. Output the result for caves 0 to N-2
    for (int i = 0; i < n - 1; i++) {
        cout << res[i] << (i == n - 2 ? "" : " ");
    }
    cout << "\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...