Submission #1223465

#TimeUsernameProblemLanguageResultExecution timeMemory
1223465abczzBoard Game (JOI24_boardgame)C++20
3 / 100
88 ms94652 KiB
#include <iostream>
#include <queue>
#include <vector>
#include <array>
#include <algorithm>
#include <cmath>
#define ll long long

using namespace std;

array<ll, 2> operator+(array<ll, 2> a, array<ll, 2> b) {
  return {a[0]+b[0], a[1]+b[1]};
}
queue <ll> Q;
priority_queue <array<ll, 2>, vector<array<ll, 2>>, greater<array<ll, 2>>> pq, U[2];
vector <ll> adj[50000], X;
bool B[50000];
string S;
ll dp[50000][225], mn[50000];
array <ll, 2> stop[50001];
ll n, m, k, a, b, rt, dist[50000], dist2[50000], F[50000], cost[50000];
void search(ll k, ll dlt) {
  for (int i=0; i<n; ++i) cost[i] = (ll)1e18, B[i] = 0;
  pq.push({0, rt});
  cost[rt] = 0;
  while (!pq.empty()) {
    auto [w, u] = pq.top();
    pq.pop();
    if (cost[u] != w) continue;
    for (auto v : adj[u]) {
      if (cost[v] > cost[u] + 1 + (S[v] == '1' ? k : 0)) {
        cost[v] = cost[u] + 1 + (S[v] == '1' ? k : 0);
        B[v] = B[u] | (S[u] == '1');
        pq.push({cost[v], v});
      }
    }
  }
  for (int i=0; i<n; ++i) F[i] = min(F[i], cost[i]-(i != rt && S[i] == '1' ? k : 0)-(B[i] ? k : 0)+dlt);
}
int main() {
  cin >> n >> m >> k;
  for (int i=0; i<m; ++i) {
    cin >> a >> b;
    --a, --b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  cin >> S;
  for (int i=0; i<n; ++i) {
    dist[i] = F[i] = mn[i] = (ll)1e18;
    if (S[i] == '1') Q.push(i), dist[i] = 0;
    for (int j=0; j<225; ++j) dp[i][j] = (ll)1e18;
  }
  while (!Q.empty()) {
    auto u = Q.front();
    Q.pop();
    for (auto v : adj[u]) {
      if (dist[v] == (ll)1e18) {
        dist[v] = dist[u] + 1;
        Q.push(v);
      }
    }
  }
  for (int i=0; i<n; ++i) {
    dist2[i] = (ll)1e18;
    if (S[i] == '1') {
      bool ok = 0;
      for (auto v : adj[i]) ok |= (S[v] == '1');
      if (ok) Q.push(i), dist2[i] = 0;
    }
  }
  while (!Q.empty()) {
    auto u = Q.front();
    Q.pop();
    for (auto v : adj[u]) {
      if (dist2[v] == (ll)1e18) {
        dist2[v] = dist2[u] + 1;
        Q.push(v);
      }
    }
  }
  ll s = 0;
  for (int i=0; i<n; ++i) {
    if (!dist[i]) dist[i] = 2;
    if (!dist2[i]) dist2[i] = 1;
  }
  for (int i=0; i<k; ++i) {
    cin >> a;
    --a;
    if (!i) rt = a;
    else X.push_back(a), s += dist[a];
  }
  S[rt] = '0';
  Q.push(rt);
  F[rt] = 0;
  while (!Q.empty()) {
    auto u = Q.front();
    Q.pop();
    for (auto v : adj[u]) {
      if (F[v] > F[u]+1) {
        F[v] = F[u]+1;
        if (S[v] != '1') Q.push(v);
      }
    }
  }
  sort(X.begin(), X.end(), [](auto a, auto b) {
    return dist2[a]-dist[a] < dist2[b]-dist[b];
  });
  if (k <= (ll)sqrt(n)) {
    search(2*X.size(), s);
    for (int i=0; i<X.size(); ++i) {
      s -= dist[X[i]]-dist2[X[i]];
      if (dist2[X[i]] == (ll)1e18) break;
      search(2*X.size()-i-1, s);
    }
  }
  else {
    for (auto u : X) {
      stop[max(0LL, dist2[u]-dist[u])] = stop[max(0LL, dist2[u]-dist[u])] + array<ll, 2>{-1, dist2[u]-dist[u]};
    }
    stop[0] = stop[0] + array<ll, 2>{2*(ll)X.size(), s};
    for (int i=1; i<n; ++i) {
      stop[i] = stop[i-1] + stop[i];
    }
    mn[rt] = dp[rt][0] = 0;
    U[0].push({0, rt});
    for (int t=0; t<n; ++t) {
      if (U[0].empty()) break;
      while (!U[0].empty()) {
        auto [w, u] = U[0].top();
        U[0].pop();
        if (dp[u][t-mn[u]] != w) break;
        for (auto v : adj[u]) {
          if (mn[v] == 1e18) mn[v] = t + (S[v] == '1');
          if (t+(S[v]=='1')-mn[v] < 225 && dp[v][t+(S[v]=='1')-mn[v]] > w+1) {
            dp[v][t+(S[v]=='1')-mn[v]] = w+1;
            U[S[v]=='1'].push({w+1, v});
          }
        }
      }
      swap(U[0], U[1]);
    }
    for (int i=0; i<n; ++i) {
      for (int j=0; j<225; ++j) {
        if (dp[i][j] == (ll)1e18 || (j == 0 && mn[i] == 0)) continue;
        ll u = mn[i]+j-1-(S[i] == '1');
        if (u < 0) continue;
        F[i] = min(F[i], dp[i][j] + u * stop[u][0] + stop[u][1]);
      }
    }
  }
  for (int i=0; i<n; ++i) cout << F[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...