제출 #678086

#제출 시각아이디문제언어결과실행 시간메모리
678086qwerasdfzxcl열쇠 (IOI21_keys)C++17
67 / 100
3072 ms62492 KiB
#include <bits/stdc++.h> using namespace std; const int n_max = 301000; const int k_max = 301000; vector<pair<int,int>> adj[n_max]; bool visited[n_max]; int original_key[n_max]; int has_key[k_max]; vector<int> blocked[k_max]; vector<int> P, INV; void erase_all(vector<int> st1, vector<int> st2, vector<int> st3){ for (auto &x:st1) visited[x] = false; for (auto &x:st2) has_key[x] = false; for (auto &x:st3) blocked[x].clear(); } int n; vector<int> rans; int explore(int x, bool flag=0) { int ox = x; vector<int> st1, st2, st3; visited[x] = true; st1.push_back(x); queue<int> q; q.push(x); int ans = 0; while(!q.empty()) { const int next = q.front(); q.pop(); ans++; int new_key = original_key[next]; if(!has_key[new_key]) { has_key[new_key] = true; st2.push_back(new_key); for(int i: blocked[new_key]) { if(!visited[i]) { visited[i] = true; st1.push_back(i); if (INV[i] < INV[ox]){ erase_all(st1, st2, st3); return -1; } q.push(i); } } } for(pair<int,int> p: adj[next]) { if(has_key[p.first]) { // i have the key if(!visited[p.second]) { // put in the queue visited[p.second] = true; st1.push_back(p.second); if (INV[p.second] < INV[ox]){ erase_all(st1, st2, st3); return -1; } q.push(p.second); } } else { // it may be unblocked later //assert(p.first < k_max); blocked[p.first].push_back(p.second); st3.push_back(p.first); } } } if (flag) for (auto &x:st1) rans[x] = 1; erase_all(st1, st2, st3); return ans; } vector<int> find_reachable(vector<int> r, vector<int> u, vector<int> v, vector<int> c) { int m = c.size(); n = r.size(); for(int i=0; i<n; i++) { original_key[i] = r[i]; } for(int i=0; i<m; i++) { adj[u[i]].emplace_back(c[i], v[i]); adj[v[i]].emplace_back(c[i], u[i]); } for (int i=0;i<n;i++) P.push_back(i); mt19937 rng(694201557); shuffle(P.begin(), P.end(), rng); INV.resize(n); for (int i=0;i<n;i++) INV[P[i]] = i; int a[n]; int s = n+1; vector<int> candidate; for(int i=0; i<n; i++) { int v = P[i]; a[v] = explore(v); if (a[v]!=-1){ if (s > a[v]){ candidate.clear(); s = a[v]; candidate.push_back(v); } else if (s==a[v]){ candidate.push_back(v); } } } rans.resize(n); for (auto &x:candidate) explore(x, 1); return rans; }
#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...