Submission #568869

#TimeUsernameProblemLanguageResultExecution timeMemory
568869_karan_gandhiSwapping Cities (APIO20_swap)C++17
6 / 100
2037 ms75704 KiB
#include "swap.h" #include <bits/stdc++.h> using namespace std; #define ll long long #define all(v) v.begin(), v.end() #define endl '\n' #define pl(var) " [" << #var << ": " << (var) << "] " template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "[" << p.first << ", " << p.second << "]"; } template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) { cout << "["; for(int i = 0; i < (int)v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";} template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) { cin >> p.first; return cin >> p.second; } const int LOG = 20; const int inf = 1e9 + 7; struct DSU { // Sorry UFDS int n, m; vector<int> p, s, degree, dep; vector<bool> swappable; vector<int> swap_cost; vector<vector<int>> jumpNode, jumpMinSwap, adj; int next_node; void init(int _n, int _m) { n = _n; m = _m; next_node = n; p = vector<int>(n + m + 1); // n leaves and m internal nodes iota(all(p), 0); degree = vector<int>(n, 0); swappable = vector<bool>(n + m + 1, 0); swap_cost = vector<int>(n + m + 1, inf); jumpNode = vector<vector<int>>(n + m + 1, vector<int>(LOG)); jumpMinSwap = vector<vector<int>>(n + m + 1, vector<int>(LOG)); } int get(int x) { return p[x] == x ? p[x] : get(p[x]); // no path compression } void unite(int a, int b, int wt) { degree[a]++; degree[b]++; int pa = get(a); int pb = get(b); if (pa == pb) { p[pa] = next_node; swappable[next_node] = 1; swap_cost[pa] = wt; next_node++; return; } bool _swappable = 0; if (degree[a] >= 3 || degree[b] >= 3) _swappable = 1; p[next_node] = next_node; p[pa] = next_node; p[pb] = next_node; swappable[next_node] = (_swappable | swappable[pa] | swappable[pb]); if (swappable[next_node]) swap_cost[next_node] = wt; next_node++; } void init_lca() { adj.resize(n + m + 1); dep.resize(n + m + 1); // cout << swappable << endl; // cout << swap_cost << endl; for (int i = 0; i < n + m + 1; i++) { adj[p[i]].push_back(i); jumpNode[i][0] = p[i]; // parent of the ith node jumpMinSwap[i][0] = swap_cost[i]; } for (int i = 1; i < LOG; i++) { for (int j = 0; j < n + m + 1; j++) { jumpNode[j][i] = jumpNode[jumpNode[j][i - 1]][i - 1]; jumpMinSwap[j][i] = min(jumpMinSwap[j][i - 1], jumpMinSwap[jumpNode[j][i - 1]][i - 1]); } } init_dfs(next_node - 1, 0); } pair<int, int> kth(int u, int k) { int pow = LOG - 1; int res = inf; while (k > 0) { while (k < (1 << pow)) pow--; res = min(res, jumpMinSwap[u][pow]); u = jumpNode[u][pow]; k -= (1 << pow); } return make_pair(u, res); } void init_dfs(int u, int d) { // cout << pl(u) << endl; dep[u] = d; for (int v : adj[u]) if (v != u) init_dfs(v, d + 1); } int lca(int a, int b) { if (dep[a] < dep[b]) swap(a, b); a = kth(a, dep[a] - dep[b]).first; if (a == b) return a; int pow = LOG - 1; while (pow >= 0) { if (jumpNode[a][pow] != jumpNode[b][pow]) { a = jumpNode[a][pow]; b = jumpNode[b][pow]; } pow--; } assert(jumpNode[a][0] == jumpNode[b][0]); return jumpNode[a][0]; } int when_swappable(int a, int b) { int l = lca(a, b); return kth(l, dep[l] + 1).second; } }; int n, m; vector<vector<pair<int, int>>> adj; vector<pair<int, pair<int, int>>> edges; DSU dsu; void init(int N, int M, vector<int> U, vector<int> V, vector<int> W) { n = N; m = M; adj.resize(n); for (int i = 0; i < m; i++) { adj[U[i]].emplace_back(V[i], W[i]); adj[V[i]].emplace_back(U[i], W[i]); edges.emplace_back(W[i], make_pair(U[i], V[i])); } sort(all(edges)); dsu.init(n, m); for (auto edge : edges) { // cout << edge << endl; dsu.unite(edge.second.first, edge.second.second, edge.first); } dsu.init_lca(); } int getMinimumFuelCapacity(int x, int y) { // int ptr = 0; // DSU dsu; // dsu.init(n); // while (!dsu.is_swappable(x, y) && ptr < m) { // dsu.unite(edges[ptr].second.first, edges[ptr].second.second); // ptr++; // } // if (!dsu.is_swappable(x, y)) return -1; // assert(ptr != 0); // return edges[ptr - 1].first; int res = dsu.when_swappable(x, y); return res >= inf ? -1 : res; // return -1; }
#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...