제출 #1333344

#제출 시각아이디문제언어결과실행 시간메모리
1333344patgraBoard Game (JOI24_boardgame)C++20
36 / 100
575 ms1114112 KiB
#include <bits/stdc++.h>

#define rep(a,b,c) for(auto a = (b); a != (c); a++)
#define repD(a,b,c) for(auto a = (b); a != (c); a--)
#define repIn(a, b) for(auto& a : (b))
#define repIn2(a, b, c) for(auto& [a, b] : (c))

constexpr bool dbg = 1;
#define DEBUG if constexpr(dbg)
#define DC DEBUG std::cerr
#define eol std::endl

#define ll long long
#define ld long double
#define pb push_back
#define rg ranges

using namespace std;

constexpr int inf = 1e9 + 2;

int n, m, k;
vector<vector<int>> g;
vector<int> isStop;
vector<int> others;
vector<int> dist, closestStop, closestTwo;
vector<vector<int>> skipCostV;

void bfs(vector<int> starts, bool zerStop=0) {
    dist.resize(n + 1, inf);
    deque<int> q;
    repIn(i, starts) q.pb(i), dist[i] = 0;
    vector<int> was(n + 1, 0);
    while(q.size()) {
        auto v = q.front();
        q.pop_front();
        if(was[v]) continue;
        was[v] = 1;
        repIn(u, g[v]) {
            if(zerStop && isStop[u]) {
                if(dist[u] > dist[v]) dist[u] = dist[v], q.push_front(u);
            }
            else if(dist[u] > dist[v] + 1) dist[u] = dist[v] + 1, q.pb(u);
        }
    }
}

int32_t main() {
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    cin >> n >> m >> k;
    g.resize(n + 1);
    isStop.resize(n + 1);
    rep(i, 0, m) {
        int a, b;
        cin >> a >> b;
        g[a].pb(b);
        g[b].pb(a);
    }
    char c;
    rep(i, 1, n + 1) cin >> c, isStop[i] = c == '1';
    k--;
    others.resize(k);
    int start;
    cin >> start;
    rep(i, 0, k) cin >> others[i];
    vector<int> V;
    rep(i, 1, n + 1) if(isStop[i]) V.pb(i);
    bfs(V);
    swap(dist, closestStop);
    V.clear();
    rep(v, 1, n + 1) if(isStop[v]) repIn(u, g[v]) if(isStop[u] && u > v) V.pb(v), V.pb(u);
    bfs(V, 1);
    swap(dist, closestTwo);
    int cntStop = 0;
    rep(v, 1, n + 1) cntStop += isStop[v];

    skipCostV.resize(n + 1, vector<int>(cntStop + 1));
    rep(v, 1, n + 1) rep(i, 1, cntStop + 1) { skipCostV[v][i] = min(closestStop[v] + 2 * (i - !isStop[v]), closestTwo[v] + i - !isStop[v]); }
    vector<int> skipCost(cntStop + 1);
    rep(i, 0, cntStop + 1) repIn(v, others) skipCost[i] += skipCostV[v][i];
    if(isStop[start]) {
        rg::reverse(skipCost);
        skipCost.pb(0);
        rg::reverse(skipCost);
    }
    cntStop++;

    vector<int> ans(n + 1, inf), dist2(n + 1, inf);
    dist.resize(n + 1, inf);
    int wholeSum = 0;
    repIn(i, skipCost) wholeSum += i;
    queue<pair<int, int>> q, q2;
    dist[start] = dist2[start] = 0;
    q.push({start, 0});
    int lvl = 0;
    int prefSum = 0;
    while(q.size() || q2.size()) {
        if(q.empty()) swap(q, q2), prefSum = skipCost[++lvl];
        auto [v, d] = q.front();
        q.pop();
        if(dist[v] < d) continue;
        dist[v] = d;
        ans[v] = min(ans[v], d + prefSum);
        if(isStop[v]) repIn(u, g[v]) if(dist2[u] > d + 1) dist2[u] = d + 1, q2.push({u, d + 1});
        if(!isStop[v]) repIn(u, g[v]) if(dist[u] > d + 1) dist[u] = dist2[u] = d + 1, q.push({u, d + 1});
    }
    rep(i, 1, n + 1) cout << ans[i] << '\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...