Submission #1064686

#TimeUsernameProblemLanguageResultExecution timeMemory
1064686sammyuriSwapping Cities (APIO20_swap)C++17
100 / 100
304 ms39364 KiB
#include "swap.h" #include <bits/stdc++.h> using namespace std; /* a component becomes valid as soon as there is either a loop or a node with degree 3+ if it is just a chain, clearly impossible use persistent DSU and find for each node, the minimum time until it is part of a valid component */ int n, m; int curtime = 0; const int MAXN = 1e5 + 5; map<int, int> dsu[MAXN]; int sz[MAXN]; int mintime[MAXN]; bool good[MAXN]; int deg[MAXN]; vector<int> active_nodes[MAXN]; const int INF = 2e9; int find(int node, int time) { auto it = dsu[node].upper_bound(time); it --; if ((*it).second == node) return node; return find((*it).second, time); } void init(int N, int M, std::vector<int> U, std::vector<int> V, std::vector<int> W) { n = N, m = M; curtime = 0; for (int i = 0; i < n; i ++) { mintime[i] = INF; dsu[i][0] = i; active_nodes[i].push_back(i); sz[i] = 1; deg[i] = 0; good[i] = false; } vector<pair<int, pair<int, int>>> edges; for (int i = 0; i < M; i ++) { edges.push_back({W[i], {U[i], V[i]}}); } sort(edges.begin(), edges.end()); for (auto ee : edges) { int a = ee.second.first, b = ee.second.second; curtime = ee.first; bool madegood = false; // check if made good deg[a] ++; deg[b] ++; if (deg[a] >= 3 || deg[b] >= 3) madegood = true; a = find(a, curtime); b = find(b, curtime); if (a == b) madegood = true; // unite components if (a != b) { if (sz[a] > sz[b]) swap(a, b); sz[b] += sz[a]; for (auto aa : active_nodes[a]) active_nodes[b].push_back(aa); active_nodes[a].clear(); dsu[a][curtime] = b; } good[b] = good[b] | good[a] | madegood; if (good[b]) { for (auto aa : active_nodes[b]) mintime[aa] = curtime; active_nodes[b].clear(); } } // for (int i = 0; i < n; i ++) // cout << mintime[i] << " "; cout << endl; } int getMinimumFuelCapacity(int X, int Y) { // lower bound int req = min(mintime[X], mintime[Y]); // find smallest time until they are in same component curtime = 1; while (X != Y) { auto itx = dsu[X].lower_bound(curtime), ity = dsu[Y].lower_bound(curtime); int nextmin = 2e9; if (itx != dsu[X].end() && X != (*itx).second) nextmin = min(nextmin, (*itx).first); if (ity != dsu[Y].end() && Y != (*ity).second) nextmin = min(nextmin, (*ity).first); // cout << X << " " << Y << " " << curtime << endl; // cout << nextmin << endl; curtime = nextmin; if (itx != dsu[X].end() && (*itx).first == curtime) X = (*itx).second; if (ity != dsu[Y].end() && (*ity).first == curtime) Y = (*ity).second; } int ans = max(req, curtime); if (ans == INF) return -1; return ans; }
#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...