Submission #436227

#TimeUsernameProblemLanguageResultExecution timeMemory
436227CodePlatinaFountain Parks (IOI21_parks)C++17
55 / 100
3582 ms93896 KiB
#include "parks.h" #include <iostream> #include <vector> #include <algorithm> #include <tuple> #include <random> #include <chrono> #define pii pair<int, int> #define ff first #define ss second using namespace std; const int INF = 202020; vector<pii> lsX[INF]; vector<pii> lsY[INF]; vector<pii> eg, tr; int par[202020]; int fnd(int x) { return x == par[x] ? x : par[x] = fnd(par[x]); } void uni(int x, int y) { par[fnd(x)] = fnd(y); } vector<int> U, V, A, B; vector<int> gph[404040]; int ord[404040]; int scc[404040]; int scnt = 0, cnt = 0; vector<int> S; int dfs(int x, int p) { int ret = ord[x] = ++cnt; S.push_back(x); for(int y : gph[x]) if(y != p) { if(!ord[y]) ret = min(ret, dfs(y, x)); else if(!scc[y]) ret = min(ret, ord[y]); } if(ret >= ord[x]) { ++scnt; while(S.back() != x) scc[S.back()] = scnt, S.pop_back(); scc[S.back()] = scnt, S.pop_back(); } return ret; } int construct_roads(vector<int> x, vector<int> y) { int n = x.size(); for(int i = 0; i < n; ++i) lsX[x[i]].push_back({y[i], i}); for(int i = 0; i < n; ++i) lsY[y[i]].push_back({x[i], i}); for(int i = 0; i < INF; ++i) { sort(lsX[i].begin(), lsX[i].end()); for(int j = 0; j < (int)lsX[i].size() - 1; ++j) if(lsX[i][j + 1].ff - lsX[i][j].ff == 2) eg.push_back({lsX[i][j].ss, lsX[i][j + 1].ss}); } for(int i = 0; i < INF; ++i) { sort(lsY[i].begin(), lsY[i].end()); for(int j = 0; j < (int)lsY[i].size() - 1; ++j) if(lsY[i][j + 1].ff - lsY[i][j].ff == 2) eg.push_back({lsY[i][j].ss, lsY[i][j + 1].ss}); } unsigned seed = chrono::steady_clock::now().time_since_epoch().count(); mt19937 rng(seed); for(int cs = 0; cs < 30; ++cs) { shuffle(eg.begin(), eg.end(), rng); for(int i = 0; i < 202020; ++i) par[i] = i; tr.clear(); for(auto i : eg) if(fnd(i.ff) != fnd(i.ss)) tr.push_back(i), uni(i.ff, i.ss); if(tr.size() != n - 1) return 0; pii C[n - 1], D[n - 1]; vector<pii> pr; int c = 0; for(auto [i, j] : tr) { if(x[i] == x[j]) { C[c] = {x[i] - 1, y[i] + 1}; D[c] = {x[i] + 1, y[i] + 1}; } else { C[c] = {x[i] + 1, y[i] - 1}; D[c] = {x[i] + 1, y[i] + 1}; } pr.push_back(C[c]); pr.push_back(D[c]); ++c; } sort(pr.begin(), pr.end()); pr.resize(unique(pr.begin(), pr.end()) - pr.begin()); int E[n - 1], F[n - 1]; for(int i = 0; i < n - 1; ++i) E[i] = lower_bound(pr.begin(), pr.end(), C[i]) - pr.begin(); for(int i = 0; i < n - 1; ++i) F[i] = lower_bound(pr.begin(), pr.end(), D[i]) - pr.begin(); int N = pr.size(); vector<pii> ls[N]; for(int i = 0; i < n - 1; ++i) ls[E[i]].push_back({i, 0}); for(int i = 0; i < n - 1; ++i) ls[F[i]].push_back({i, 1}); cnt = scnt = 0; for(int i = 0; i < 2 * n; ++i) gph[i].clear(), ord[i] = scc[i] = 0; S.clear(); for(int i = 0; i < N; ++i) { int sz = ls[i].size(); for(int j = 0; j < sz; ++j) { for(int k = 0; k < sz; ++k) { if(j != k) { int p = ls[i][j].ff + ls[i][j].ss * n; int q = ls[i][k].ff + (!ls[i][k].ss) * n; gph[p].push_back(q); } } } } for(int i = 0; i < 2 * n; ++i) if(!ord[i]) dfs(i, -1); bool flag = true; for(int i = 0; i < n - 1; ++i) if(scc[i] == scc[i + n]) flag = false; if(!flag) continue; for(int i = 0; i < n - 1; ++i) { U.push_back(tr[i].ff); V.push_back(tr[i].ss); if(scc[i] < scc[i + n]) { A.push_back(C[i].ff); B.push_back(C[i].ss); } else { A.push_back(D[i].ff); B.push_back(D[i].ss); } } build(U, V, A, B); return 1; } return 0; }

Compilation message (stderr)

parks.cpp: In function 'int construct_roads(std::vector<int>, std::vector<int>)':
parks.cpp:75:22: warning: comparison of integer expressions of different signedness: 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   75 |         if(tr.size() != n - 1) return 0;
      |            ~~~~~~~~~~^~~~~~~~
#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...