Submission #430561

#TimeUsernameProblemLanguageResultExecution timeMemory
430561keko37From Hacks to Snitches (BOI21_watchmen)C++14
100 / 100
3001 ms173708 KiB
#include<bits/stdc++.h> using namespace std; typedef long long llint; typedef pair <int, int> pi; const int MAXN = 250005; const llint INF = 1000000000000000000LL; int n, m, k; int d[MAXN], ost[MAXN], koji[MAXN], prv[MAXN], nxt[MAXN]; llint best[MAXN], dist[3005][3005]; vector <pi> edges; bool watched[MAXN]; vector <int> good, bad, sus_good[MAXN], sus_bad[MAXN]; void build () { for (int i = 1; i <= n; i++) { if (watched[i]) bad.push_back(i); else good.push_back(i); } for (int i = 0; i < bad.size(); i++) { koji[bad[i]] = i; } for (auto pp : edges) { int a = pp.first, b = pp.second; if (watched[b]) sus_bad[a].push_back(b); else sus_good[a].push_back(b); if (watched[a]) sus_bad[b].push_back(a); else sus_good[b].push_back(a); } } priority_queue < pair <llint, pi> > pq; void dijkstra () { for (int i = 1; i <= n; i++) { best[i] = INF; } for (int i = 0; i < bad.size(); i++) { int node = bad[i]; for (int j = 0; j < d[node]; j++) { dist[i][j] = INF; } } best[1] = 0; pq.push({0, {-1, 1}}); while (!pq.empty()) { llint pq_dist = -pq.top().first; int jen = pq.top().second.first; int dva = pq.top().second.second; pq.pop(); int node; if (jen == -1) { node = dva; if (pq_dist > best[node]) continue; } else { node = bad[jen]; if (pq_dist > dist[jen][dva]) continue; } if (!watched[node]) { for (auto sus : sus_good[node]) { llint novi = best[node] + 1; if (novi < best[sus]) { best[sus] = novi; pq.push({-novi, {-1, sus}}); } } for (auto sus : sus_bad[node]) { llint novi = best[node] + 1; llint T = ((ost[sus] - novi) % d[sus] + d[sus]) % d[sus] + novi; int curr_ost = novi % d[sus]; if (novi < dist[koji[sus]][curr_ost] && novi < T) { dist[koji[sus]][curr_ost] = novi; pq.push({-novi, {koji[sus], curr_ost}}); } curr_ost = (T + 1) % d[sus]; if (T + 1 < dist[koji[sus]][curr_ost]) { dist[koji[sus]][curr_ost] = T + 1; pq.push({-(T + 1), {koji[sus], curr_ost}}); } } } else { if (best[node] == INF) { best[node] = pq_dist; for (auto sus : sus_good[node]) { llint novi = best[node] + 1; if (novi < best[sus]) { best[sus] = novi; pq.push({-novi, {-1, sus}}); } } } vector <int> sus_tmp; for (auto sus : sus_bad[node]) { if (sus == prv[node] || sus == nxt[node]) continue; llint novi = pq_dist + 1; llint T = ((ost[sus] - novi) % d[sus] + d[sus]) % d[sus] + novi; int curr_ost = novi % d[sus]; if (novi < dist[koji[sus]][curr_ost] && novi < T) { dist[koji[sus]][curr_ost] = novi; pq.push({-novi, {koji[sus], curr_ost}}); } if (T % d[node] != ost[node]) { curr_ost = (T + 1) % d[sus]; if (T + 1 < dist[koji[sus]][curr_ost]) { dist[koji[sus]][curr_ost] = T + 1; pq.push({-(T + 1), {koji[sus], curr_ost}}); } } else { sus_tmp.push_back(sus); int t = ((pq_dist % d[node] - (T + 1)) % d[node] + d[node]) % d[node] + (T + 1); int T2 = ((ost[sus] - (t + 1)) % d[sus] + d[sus]) % d[sus] + (t + 1); curr_ost = (t + 1) % d[sus]; if (t + 1 < dist[koji[sus]][curr_ost] && t + 1 < T2) { dist[koji[sus]][curr_ost] = t + 1; pq.push({-(t + 1), {koji[sus], curr_ost}}); } curr_ost = (T2 + 1) % d[sus]; if (T2 + 1 < dist[koji[sus]][curr_ost] && T2 % d[node] != ost[node]) { dist[koji[sus]][curr_ost] = T2 + 1; pq.push({-(T2 + 1), {koji[sus], curr_ost}}); } } } sus_bad[node] = sus_tmp; int sus = prv[node]; llint novi = pq_dist + 1; int curr_ost = novi % d[node]; if (curr_ost != ost[node] && curr_ost != ost[sus] && novi < dist[koji[sus]][curr_ost]) { dist[koji[sus]][curr_ost] = novi; pq.push({-novi, {koji[sus], curr_ost}}); } sus = nxt[node]; if (curr_ost != ost[sus] && novi < dist[koji[sus]][curr_ost]) { dist[koji[sus]][curr_ost] = novi; pq.push({-novi, {koji[sus], curr_ost}}); } sus = node; if (curr_ost != ost[sus] && novi < dist[koji[sus]][curr_ost]) { dist[koji[sus]][curr_ost] = novi; pq.push({-novi, {koji[sus], curr_ost}}); } } } } int main () { ios_base::sync_with_stdio(false); cin.tie(0); cin >> n >> m; for (int i = 0; i < m; i++) { int a, b; cin >> a >> b; edges.push_back({a, b}); } cin >> k; for (int i = 1; i <= k; i++) { int len; cin >> len; vector <int> tmp; for (int j = 0; j < len; j++) { int node; cin >> node; tmp.push_back(node); watched[node] = 1; d[node] = len; ost[node] = j; } for (int i = 0; i < len; i++) { prv[tmp[i]] = tmp[(i - 1 + len) % len]; nxt[tmp[i]] = tmp[(i + 1) % len]; } } build(); dijkstra(); if (best[n] == INF) cout << "impossible"; else cout << best[n]; return 0; }

Compilation message (stderr)

watchmen.cpp: In function 'void build()':
watchmen.cpp:23:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   23 |     for (int i = 0; i < bad.size(); i++) {
      |                     ~~^~~~~~~~~~~~
watchmen.cpp: In function 'void dijkstra()':
watchmen.cpp:39:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   39 |     for (int i = 0; i < bad.size(); i++) {
      |                     ~~^~~~~~~~~~~~
#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...