Submission #1289601

#TimeUsernameProblemLanguageResultExecution timeMemory
1289601sirnickToy Train (IOI17_train)C++20
0 / 100
6 ms2424 KiB
#include <bits/stdc++.h>
using namespace std;

vector<int> who_wins(vector<int> a, vector<int> r, vector<int> u, vector<int> v) {
    int n = a.size();       // number of stations: 0..n-1
    int m = u.size();       // number of directed tracks

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

    // ---------------------------
    // 1. TARJAN for SCC
    // ---------------------------
    vector<int> disc(n, -1), low(n), st;
    vector<bool> on_st(n, false);
    int t = 0, scc_count = 0;
    vector<int> comp(n);

    function<void(int)> dfs = [&](int u) {
        disc[u] = low[u] = t++;
        st.push_back(u);
        on_st[u] = true;

        for (int x : adj[u]) {
            if (disc[x] == -1) {
                dfs(x);
                low[u] = min(low[u], low[x]);
            } else if (on_st[x]) {
                low[u] = min(low[u], disc[x]);
            }
        }
        // root of an SCC
        if (low[u] == disc[u]) {
            while (true) {
                int w = st.back(); st.pop_back();
                on_st[w] = false;
                comp[w] = scc_count;
                if (w == u) break;
            }
            scc_count++;
        }
    };

    for (int i = 0; i < n; i++)
        if (disc[i] == -1) dfs(i);

    // ---------------------------
    // 2. Condensed graph of SCCs
    // ---------------------------
    vector<vector<int>> cadj(scc_count);
    vector<int> indeg(scc_count, 0);
    vector<bool> has_charge(scc_count, false);

    for (int i = 0; i < n; i++) {
        if (r[i]) has_charge[comp[i]] = true;
    }

    for (int i = 0; i < m; i++) {
        int cu = comp[u[i]], cv = comp[v[i]];
        if (cu != cv) {
            cadj[cu].push_back(cv);
            indeg[cv]++;
        }
    }

    // ---------------------------
    // 3. Game on SCC DAG:
    // win_scc[c] = true if Arezou can force reaching a charging SCC
    // ---------------------------
    vector<int> win_scc(scc_count, false);
    queue<int> q;

    // Initial winning SCCs: ones with charging station
    for (int c = 0; c < scc_count; c++) {
        if (has_charge[c]) {
            win_scc[c] = true;
            q.push(c);
        }
    }

    // Reverse graph of condensed SCC
    vector<vector<int>> rcadj(scc_count);
    for(int c = 0; c < scc_count; c++)
        for(int nx : cadj[c])
            rcadj[nx].push_back(c);

    // Propagate wins backward: if from a SCC one can reach a winning SCC,
    // it also becomes winning because once the train enters a chosen edge,
    // the directed nature ensures eventual return to the same SCC.
    while(!q.empty()) {
        int c = q.front(); q.pop();
        for(int p : rcadj[c]) {
            if(!win_scc[p]) {
                win_scc[p] = true;
                q.push(p);
            }
        }
    }

    // ---------------------------
    // 4. Now per station: a station is winning if its SCC is winning
    // ---------------------------
    vector<int> ans(n);
    for (int i = 0; i < n; i++) {
        ans[i] = win_scc[comp[i]] ? 1 : 0;
    }
    return ans;
}
#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...