Submission #1369015

#TimeUsernameProblemLanguageResultExecution timeMemory
1369015gelastropodBoard Game (JOI24_boardgame)C++20
0 / 100
449 ms1114112 KiB
#pragma GCC optimize("O3,inline")
#include <bits/stdc++.h>
using namespace std;
#define int long long

#define INF 100000000000LL

vector<vector<int>> adjlist;
vector<int> start;

signed main() {
    //ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int N, M, K, a, b; cin >> N >> M >> K;
    adjlist.resize(N, vector<int>());
    for (int i = 0; i < M; i++) {
        cin >> a >> b; a--, b--;
        adjlist[a].push_back(b);
        adjlist[b].push_back(a);
    }
    string S; cin >> S;
    for (int i = 0; i < K; i++) {
        cin >> a; a--;
        start.push_back(a);
    }
    bitset<50005> bs1, bs2;
    for (int i = 0; i < N; i++) {
        if (S[i] == '0') continue;
        bs1[i] = 1;
        for (int j : adjlist[i]) if (S[j] == '1') bs2[i] = 1;
    }
    vector<int> A(N, INF), B(N, INF), anss(N, INF), minstop(N, INF), cost = {0LL};
    deque<pair<int, int>> bfs;
    for (int i = 0; i < N; i++) if (bs1[i]) bfs.push_front({i, 0LL});
    while (bfs.size()) {
        auto i = bfs.front(); bfs.pop_front();
        if (A[i.first] <= i.second) continue;
        if (i.second) A[i.first] = i.second;
        for (int j : adjlist[i.first]) bfs.push_back({j, i.second + 1});
    }
    for (int i = 0; i < N; i++) if (bs1[i] && A[i] > 2) A[i] = 2;
    for (int i = 0; i < N; i++) A[i] -= 2;
    for (int i = 0; i < N; i++) if (bs2[i]) bfs.push_front({i, 0LL});
    while (bfs.size()) {
        auto i = bfs.front(); bfs.pop_front();
        if (B[i.first] <= i.second) continue;
        B[i.first] = i.second;
        for (int j : adjlist[i.first]) {
            if (bs1[j]) bfs.push_front({j, i.second});
            else bfs.push_back({j, i.second + 1});
        }
    }
    vector<pair<int, pair<int, int>>> vals = {{0LL, {0LL, 0LL}}};
    for (int i = 1; i < K; i++) vals.push_back({B[start[i]] - A[start[i]], {A[start[i]], B[start[i]]}});
    sort(vals.begin(), vals.end());
	//for (int i = 1; i < K; i++) cout << A[start[i]] << ' ' << B[start[i]] << '\n';    
	if (0 && K <= 200) {
        queue<pair<int, pair<int, int>>> bfs1, bfs2;
        bitset<50005> flag;
        vector<int> dist(N, INF);
        for (int i = 0; i < K; i++) {
            flag = 0;
            fill(dist.begin(), dist.end(), INF);
            bfs1.push({start[0], {0LL, 0LL}});
            dist[start[0]] = 0;
            while (bfs1.size() || bfs2.size()) {
                int choice = (bfs1.empty() || (bfs2.size() && dist[bfs2.front().first] < dist[bfs1.front().first]));
                pair<int, pair<int, int>> j;
                if (!choice) {j = bfs1.front(); bfs1.pop();}
                else {j = bfs2.front(); bfs2.pop();}
                if (dist[j.first] < j.second.second) continue;
                flag[j.first] = j.second.first;
                for (int k : adjlist[j.first]) {
                    if (bs1[j.first] && j.first != start[0]) {
                        if (dist[k] <= dist[j.first] + 2 * K - 1 - i) continue;
                        dist[k] = dist[j.first] + 2 * K - 1 - i;
                        bfs2.push({k, {1LL, dist[k]}});
                    }
                    else {
                        if (dist[k] <= dist[j.first] + 1) continue;
                        dist[k] = dist[j.first] + 1;
                        bfs1.push({k, {j.second.first, dist[k]}});
                    }
                }
            }
			//cout << flag << '\n';
			int offset = 0;
			//for (int i : dist) cout << i << ' ';
            for (int j = 0; j < K; j++) offset += (j <= i ? vals[j].second.second : vals[j].second.first);
            for (int j = 0; j < N; j++) anss[j] = min(anss[j], dist[j] + flag[j] * offset);
        }
        for (int i : anss) cout << i << '\n';
        return 0;
    }
    bfs.push_front({start[0], 0});
    while (bfs.size()) {
        auto i = bfs.front(); bfs.pop_front();
        if (minstop[i.first] <= i.second) continue;
        minstop[i.first] = i.second;
        for (int j : adjlist[i.first]) {
            if (bs1[i.first] && i.first != start[0]) bfs.push_back({j, i.second + 1});
            else bfs.push_front({j, i.second});
        }
    }
    vector<vector<int>> findist(N / K + 1, vector<int>(N, INF));
    bfs.push_front({start[0], 0});
    findist[0][start[0]] = 0;
    while (bfs.size()) {
        auto i = bfs.front(); bfs.pop_front();
        int cd = findist[i.second - minstop[i.first]][i.first];
        if (bs1[i.first] && (i.first != start[0] || i.second)) i.second++;
        for (int j : adjlist[i.first]) {
            if (i.second > minstop[j] + N / K || findist[i.second - minstop[j]][j] != INF) continue;
            findist[i.second - minstop[j]][j] = cd + 1;
            bfs.push_front({j, i.second});
        }
    }
    int crnt = 0;
    for (int i = 1; i < K; i++) crnt += A[start[i]] + 2;
    for (int i = 1; i < N + N / K; i++) {
        cost.push_back(crnt);
        crnt += 2 * K - 1 - (int)(upper_bound(vals.begin(), vals.end(), pair<int, pair<int, int>>(i, {INF, INF})) - vals.begin());
    }
    for (int i = 0; i < N; i++) for (int j = 0; j <= N / K; j++) anss[i] = min(anss[i], findist[j][i] + cost[minstop[i] + j]);
    for (int i : anss) cout << i << '\n';
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...