Submission #965055

#TimeUsernameProblemLanguageResultExecution timeMemory
965055PanndaSwapping Cities (APIO20_swap)C++17
23 / 100
2021 ms524288 KiB
#include "swap.h" #include <bits/stdc++.h> using namespace std; struct DSU { vector<int> f; // vector<int> siz; vector<int> deg; vector<bool> ok; DSU(int n) : f(n), deg(n, 0), ok(n, false) { iota(f.begin(), f.end(), 0); } int leader(int u) { while (u != f[u]) u = f[u] = f[f[u]]; return u; } bool unionize(int u0, int v0) { int u = leader(u0); int v = leader(v0); if (u == v) { ok[u] = true; return false; } // if (siz[u] > siz[v]) swap(u, v); // siz[v] += siz[u]; if (++deg[u0] >= 3 || ++deg[v0] >= 3) ok[v] = true; ok[v] = ok[v] | ok[u]; f[u] = v; return true; } bool same(int u, int v) { return leader(u) == leader(v); } bool isOk(int u) { return ok[leader(u)]; } }; struct LiteDSU { vector<int> f; vector<int> siz; vector<bool> ok; LiteDSU(int n) : f(n), siz(n, 1), ok(n, false) { iota(f.begin(), f.end(), 0); } int leader(int u) { while (u != f[u]) u = f[u] = f[f[u]]; return u; } bool unionize(int u, int v) { u = leader(u); v = leader(v); if (u == v) return false; if (siz[u] > siz[v]) swap(u, v); siz[v] += siz[u]; ok[v] = ok[v] | ok[u]; f[u] = v; return true; } bool same(int u, int v) { return leader(u) == leader(v); } bool isOk(int u) { return ok[leader(u)]; } }; int n, m; vector<array<int, 3>> edges; const int B = 300; vector<DSU> dsus; int b; vector<int> mp; void init(int N, int M, vector<int> U, vector<int> V, vector<int> W) { n = N; m = M; edges.resize(m); for (int i = 0; i < m; i++) { edges[i] = {U[i], V[i], W[i]}; } sort(edges.begin(), edges.end(), [&](array<int, 3> e0, array<int, 3> e1) { return e0[2] < e1[2]; }); dsus.emplace_back(n); for (b = 0; B * b < m; b++) { dsus.push_back(dsus.back()); for (int i = B * b; i < min(m, B * b + B); i++) { dsus.back().unionize(edges[i][0], edges[i][1]); } for (int u = 0; u < n; u++) dsus.back().leader(u); } b++; mp.resize(n, -1); } int getMinimumFuelCapacity(int X, int Y) { if (!dsus.back().same(X, Y) || !dsus.back().isOk(X)) return -1; int b0 = [&]() -> int { int l = 0, r = b - 2; while (l < r) { int m = (l + r + 1) >> 1; if (!dsus[m].same(X, Y) || !dsus[m].isOk(X)) { l = m; } else { r = m - 1; } } return l; }(); vector<int> dom; for (int i = B * b0; i < min(m, B * b0 + B); i++) { if (dsus[b0 + 1].same(X, edges[i][0]) || dsus[b0 + 1].same(X, edges[i][1])) { int u = dsus[b0].leader(edges[i][0]); int v = dsus[b0].leader(edges[i][1]); if (mp[u] == -1) mp[u] = 0, dom.push_back(u); if (mp[v] == -1) mp[v] = 0, dom.push_back(v); } } int c = dom.size(); int label = 0; for (int u : dom) mp[u] = label++; int x = mp[dsus[b0].leader(X)]; int y = mp[dsus[b0].leader(Y)]; LiteDSU dsu(c); int res = -2; vector<int> defer; for (int u : dom) if (dsus[b0].isOk(u)) dsu.ok[mp[u]] = true; for (int i = B * b0; i < min(m, B * b0 + B); i++) { if (dsus[b0 + 1].same(X, edges[i][0]) || dsus[b0 + 1].same(X, edges[i][1])) { int u = mp[dsus[b0].leader(edges[i][0])]; int v = mp[dsus[b0].leader(edges[i][1])]; if (dsu.same(u, v)) { dsu.ok[dsu.leader(u)] = true; } else { defer.push_back(edges[i][0]); defer.push_back(edges[i][1]); if (++dsus[b0].deg[edges[i][0]] >= 3) dsu.ok[dsu.leader(u)] = true; if (++dsus[b0].deg[edges[i][1]] >= 3) dsu.ok[dsu.leader(v)] = true; dsu.unionize(u, v); } if (dsu.same(x, y) && dsu.isOk(x)) { res = edges[i][2]; break; } } } for (int u : defer) dsus[b0].deg[u]--; for (int u : dom) mp[u] = -1; return res; }
#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...