제출 #1347306

#제출 시각아이디문제언어결과실행 시간메모리
1347306PakinDioxideBoard Game (JOI24_boardgame)C++17
100 / 100
322 ms12816 KiB
#include <bits/stdc++.h>
#define ll long long
#define int ll

using namespace std;

const int mxN = 5e4+5;

int n, m, k, a[mxN], st[mxN];
vector <int> adj[mxN];
string s;

int32_t main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n >> m >> k;
    for (int i = 0, u, v; i < m; i++) {
        cin >> u >> v;
        adj[u].emplace_back(v);
        adj[v].emplace_back(u);
    }
    cin >> s;
    for (int i = 0; i < n; i++) a[i+1] = s[i] - '0';
    for (int i = 1; i <= k; i++) cin >> st[i];
    vector <int> ST;
    for (int i = 1; i <= n; i++) if (a[i]) ST.emplace_back(i);
    auto bfs = [&] (int x, vector <int> &dis) {
        queue <int> q;
        q.emplace(x);
        dis[x] = 0;
        while (q.size()) {
            int u = q.front(); q.pop();
            for (auto v : adj[u]) if (dis[v] > dis[u] + 1) dis[v] = dis[u] + 1, q.emplace(v);
        }
    };
    if (ST.empty()) {
        vector <int> dis(n+1, INT_MAX);
        bfs(st[1], dis);
        for (int i = 1; i <= n; i++) cout << dis[i] << '\n';
        exit(0);
    } else if ((int) ST.size() == 1) {
        vector <int> dx(n+1, INT_MAX);
        bfs(ST[0], dx);
        ll cst = 0;
        for (int i = 2; i <= k; i++) cst += (dx[st[i]] == 0 ? 2 : dx[st[i]]);
        priority_queue <pair <ll, int>> q;
        vector <int> dis(n+1, INT_MAX);
        dis[st[1]] = 0;
        q.emplace(0, st[1]);
        while (q.size()) {
            auto [w, u] = q.top();
            q.pop(); w = -w;
            if (dis[u] != w) continue;
            if (u != st[1] && a[u]) w += cst;
            for (auto v : adj[u]) {
                if (dis[v] > w + 1) q.emplace(-(dis[v] = w + 1), v);
            }
        }
        for (int i = 1; i <= n; i++) cout << dis[i] << '\n';
        exit(0);
    } else if ((int) ST.size() == 2) {
        vector <int> dx1(n+1, INT_MAX), dx2(n+1, INT_MAX);
        bfs(ST[0], dx1);
        bfs(ST[1], dx2);
        ll cst = 0;
        for (int i = 2; i <= k; i++) {
            cst += min((dx1[st[i]] == 0 ? 2 : dx1[st[i]]), (dx2[st[i]] == 0 ? 2 : dx2[st[i]]));;
        }
        priority_queue <tuple <ll, int, int>> q;
        vector <vector <ll>> dis(n+1, vector <ll>(3, LLONG_MAX));
        dis[st[1]][0] = 0;
        q.emplace(0, 0, st[1]);
        while (q.size()) {
            auto [w, c, u] = q.top();
            q.pop(); w = -w;
            if (dis[u][c] != w) continue;
            if (u != st[1] && a[u]) {
                if (c == 0) c++, w += cst;
                else c++, w += min(2LL, dx1[ST[1]]) * (k - 1);
            }
            if (c > 2) continue;
            for (auto v : adj[u]) {
                if (dis[v][c] > w + 1) q.emplace(-(dis[v][c] = w + 1), c, v);
            }
        }
        for (int i = 1; i <= n; i++) cout << min({dis[i][0], dis[i][1], dis[i][2]}) << '\n';
        exit(0);
    }
    vector <int> OK, kk(n+1);
    for (auto &u : ST) for (auto &v : adj[u]) if (a[v]) { kk[u] = 1, OK.emplace_back(u); break; }
    if (OK.empty()) {
        priority_queue <tuple <ll, int, int>> q;
        vector <ll> dis(n+1, LLONG_MAX);
        for (auto &e : ST) dis[e] = 0, q.emplace(0, 0, e);
        while (q.size()) {
            auto [w, c, u] = q.top(); q.pop();
            w = -w;
            if (dis[u] != w) continue;
            for (auto v : adj[u]) {
                if (dis[v] > w + 1) q.emplace(-(dis[v] = w+1), 0, v);
            }
        }
        vector <ll> dp(n+1, 0);
        for (int i = 2; i <= k; i++) {
            ll b = dis[st[i]], mn = LLONG_MAX;
            if (b == 0) b = 2 - kk[st[i]];
            assert(b < LLONG_MAX); // --> RTE
            for (int j = 1; j <= n; j++) {
                dp[j] += min(b + 2 * (j-1), (mn == LLONG_MAX ? LLONG_MAX : mn + j));
            }
            // if (i == 2) cout << '\n';
        }
        // for (int i = 1; i <= n; i++) cout << dp[i] << ' '; cout << '\n';
        vector <vector <pair <ll, ll>>> D(n+1, vector <pair <ll, ll>> (2, make_pair(LLONG_MAX, LLONG_MAX)));
        q.emplace(0, 0, st[1]);
        D[st[1]][0] = make_pair(0, 0);
        while (q.size()) {
            auto [w, c, u] = q.top(); q.pop();
            w = -w;
            int C = (c > 0);
            if (D[u][C] != make_pair(w, c)) continue;
            if (u != st[1] && a[u]) C = 1, c++, w += dp[c] - dp[c-1];
            if (c > n) continue;
            for (auto v : adj[u]) {
                if (D[v][C].first > w + 1) {
                    q.emplace(-(D[v][C] = make_pair(w + 1, c)).first, c, v);
                } else if (D[v][C].first == w+1 && C && D[v][C].second < c) {
                    q.emplace(-(D[v][C] = make_pair(w + 1, c)).first, c, v);
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            ll ans = min(D[i][0].first, D[i][1].first);
            assert(ans < LLONG_MAX);
            cout << ans << '\n';
        }
        return 0;
    }
    priority_queue <tuple <ll, int, int>> q;
    vector <ll> dis(n+1, LLONG_MAX);
    for (auto &e : ST) q.emplace(0, 0, e);
    while (q.size()) {
        auto [w, c, u] = q.top(); q.pop();
        w = -w;
        if (w > 0 && dis[u] != w) continue;
        for (auto v : adj[u]) {
            if (dis[v] > w + 1) q.emplace(-(dis[v] = w+1), 0, v);
        }
    }
    vector <ll> dx(n+1, LLONG_MAX);
    for (auto &e : OK) dx[e] = 0, q.emplace(0, 0, e);
    while (q.size()) {
        auto [w, c, u] = q.top(); q.pop();
        w = -w;
        if (dx[u] != w) continue;
        w -= a[u];
        for (auto v : adj[u]) {
            ll nw = w + 1;
            if (dx[v] > nw) q.emplace(-(dx[v] = nw), 0, v);
        }
    }
    vector <ll> dp(n+1, 0), dp2(n+1, 0), DP(n+1, 0);
    for (int i = 2; i <= k; i++) {
        ll b = dis[st[i]], c = dx[st[i]];
        // find k such that
        // b + 2 * (k - 1) > c + k
        // b + 2 * k - 2 > c + k
        // k > c - b + 2
        ll id = c - b + 2 + 1;
        // BRUTEFORCE
        // cout << b << ' ' << c << '\n';
        // cout << id << '\n';
        // continue;
        id = max(id, 1LL);
        if (id > n) {
            dp[1] += b - 2;
            dp2[1] += 2;
        } else {
            dp[1] += b - 2;
            dp2[1] += 2;
            dp[id] -= b - 2;
            dp2[id] -= 2;
            dp[id] += c;
            dp2[id] += 1;
        }
        // for (int j = 1; j < id && j <= n; j++) dp[j] += b + 2 * (j - 1);
        // for (int j = id; j <= n; j++) dp[j] += c + j;
    }
    ll cnt = 0;
    for (int i = 1; i <= n; i++) {
        dp[i] += dp[i-1];
        cnt += dp2[i];
        DP[i] = dp[i] + cnt * i;
    }
    vector <vector <pair <ll, ll>>> D(n+1, vector <pair <ll, ll>> (2, make_pair(LLONG_MAX, LLONG_MAX)));
    q.emplace(0, 0, st[1]);
    D[st[1]][0] = make_pair(0, 0);
    while (q.size()) {
        auto [w, c, u] = q.top(); q.pop();
        w = -w;
        int C = (c > 0);
        if (D[u][C] != make_pair(w, c)) continue;
        if (u != st[1] && a[u]) C = 1, c++, w += DP[c] - DP[c-1];
        if (c > n) continue;
        for (auto v : adj[u]) {
            if (D[v][C].first > w + 1) {
                q.emplace(-(D[v][C] = make_pair(w + 1, c)).first, c, v);
            } else if (D[v][C].first == w+1 && C && D[v][C].second < c) {
                q.emplace(-(D[v][C] = make_pair(w + 1, c)).first, c, v);
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        ll ans = min(D[i][0].first, D[i][1].first);
        assert(ans < LLONG_MAX);
        cout << ans << '\n';
    }
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...