Submission #306811

#TimeUsernameProblemLanguageResultExecution timeMemory
306811quocnguyen1012Swapping Cities (APIO20_swap)C++14
100 / 100
664 ms53488 KiB
#ifndef LOCAL #include "swap.h" #endif // LOCAl #include <bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define ar array using namespace std; typedef long long ll; typedef pair<int, int> ii; const int maxn = 2e5 + 5; class DSU { public: class node { public: int pa, max_deg, cycle, updated; bool operator < (const node & other) const { return updated < other.updated; } }; vector<node> nodes[maxn]; vector<int> memb[maxn]; int deg[maxn]; void init(int n) { for(int i = 0; i < n; ++i){ memb[i].clear(); nodes[i].clear(); memb[i].pb(i); nodes[i].pb({i, 0, 0, -1}); } } int finds(int u) { return nodes[u].back().pa; } void add_edge(int u, int v, int i) { deg[u]++; deg[v]++; int new_deg = max(deg[u], deg[v]); u = finds(u); v = finds(v); if(u != v){ if(memb[u].size() < memb[v].size()) swap(u, v); for(auto & x : memb[v]){ node prv = nodes[x].back(); prv.pa = u; prv.updated = i; nodes[x].pb(prv); memb[u].pb(x); } node prv = nodes[u].back(); prv.max_deg = max(prv.max_deg, nodes[v].back().max_deg); prv.cycle |= nodes[v].back().cycle; prv.updated = i; nodes[u].pb(prv); memb[v].clear(); } node prv = nodes[u].back(); if(u == v) prv.cycle = true; prv.max_deg = max(prv.max_deg, new_deg); prv.updated = i; nodes[u].pb(prv); } node get_node(int u, int t) { return *--upper_bound(nodes[u].begin(), nodes[u].end(), (node){-1, -1, 0, t}); } }dsu; vector<ar<int, 3>> edge; int N, M; bool isValid(int u, int v, int t) { auto pu = dsu.get_node(u, t), pv = dsu.get_node(v, t); if(pu.pa != pv.pa) return false; auto val = dsu.get_node(pu.pa, t); return val.max_deg >= 3 || val.cycle; } void init(int _N, int _M, std::vector<int> U, std::vector<int> V, std::vector<int> W) { N = _N; M = _M; dsu.init(N); edge.resize(M); for(int i = 0; i < M; ++i){ edge[i] = {W[i], U[i], V[i]}; } sort(edge.begin(), edge.end()); for(int i = 0; i < M; ++i){ dsu.add_edge(edge[i][1], edge[i][2], i); } } int getMinimumFuelCapacity(int X, int Y) { int lo = 0, hi = M - 1; while(lo <= hi){ int mid = (lo + hi) / 2; if(isValid(X, Y, mid)) hi = mid - 1; else lo = mid + 1; } if(lo == M) return -1; return edge[lo][0]; } #ifdef LOCAL signed main(void){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #ifdef LOCAL freopen("A.INP", "r", stdin); freopen("A.OUT", "w", stdout); #endif // LOCAL int N, M; cin >> N >> M; vector<int> U(M), V(M), W(M); for(int i = 0; i < M; ++i){ cin >> U[i]; } for(int i = 0; i < M; ++i){ cin >> V[i]; } for(int i = 0; i < M; ++i){ cin >> W[i]; } init(N, M, U, V, W); int Q; cin >> Q; while(Q--){ int x, y; cin >> x >> y; cout << getMinimumFuelCapacity(x, y) << '\n'; } } #endif
#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...