제출 #1316350

#제출 시각아이디문제언어결과실행 시간메모리
1316350jxu자매 도시 (APIO20_swap)C++20
100 / 100
116 ms9416 KiB
#include "swap.h" #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() #define pb push_back typedef long long ll; typedef pair<int, int> pi; typedef vector<int> vi; typedef vector<ll> vl; typedef tuple<int, int, int> ti; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); #ifdef LOCAL #include <debug.h> #else #define debug(...) #define debugArr(...) #endif const int MOD = 1000000007; const char nl = '\n'; const int N = 1e5; const int inf = 2e9; int par[N], comp_size[N], merged[N], time_valid[N], deg[N]; int find(int a) { while (par[a] != a) a = par[a]; return a; } void join(int a, int b, int time) { deg[a]++; deg[b]++; bool athree = deg[a] >= 3; bool bthree = deg[b] >= 3; a = find(a); b = find(b); if (athree) time_valid[a] = min(time_valid[a], time); if (bthree) time_valid[b] = min(time_valid[b], time); if (a == b) { time_valid[a] = min(time_valid[a], time); return; } if (comp_size[a] < comp_size[b]) swap(a, b); // cout << b << " into " << a << nl; time_valid[a] = min(time_valid[a], max(time, time_valid[b])); par[b] = a; comp_size[a] += comp_size[b]; merged[b] = time; } void init(int n, int m, vector<int> U, vector<int> V, vector<int> W) { for (int i = 0; i < n; i++) { comp_size[i] = 1; par[i] = i; time_valid[i] = inf; merged[i] = 0; } vector<int> edges(m); iota(edges.begin(), edges.end(), 0); sort(edges.begin(), edges.end(), [&] (auto &a, auto &b) { return W[a] < W[b]; }); for (int &i: edges) { int u = U[i]; int v = V[i]; int w = W[i]; join(u, v, w); } } int getMinimumFuelCapacity(int X, int Y) { // ans is max(min(valid on path to root), max(merge on path to lca)) int merge_time = 0; int valid_time = inf; if (find(X) != find(Y)) return -1; int x = X; int y = Y; while(x != y) { // debug(x, y); if (comp_size[x] > comp_size[y]) swap(x, y); valid_time = min(valid_time, max(merge_time, time_valid[x])); merge_time = max(merge_time, merged[x]); x = par[x]; } // debug(x, time_valid[4]); // debug(merge_time, valid_time); int ans = merge_time; while(merged[x] != 0) { valid_time = min(valid_time, max(merge_time, time_valid[x])); merge_time = max(merge_time, merged[x]); x = par[x]; } valid_time = min(valid_time, max(merge_time, time_valid[x])); ans = max(ans, valid_time); if (ans == inf) return -1; return ans; } // struct UF { // vi id, valid, degg; // UF (int n): id(n), valid(n), degg(n) { // iota(all(id), 0); // } // int find(int a) { // if (id[a] == a) return a; // return id[a] = find(id[a]); // } // void join(int a, int b) { // degg[a]++; degg[b]++; // bool v = (degg[a] >= 3 || degg[b] >= 3); // a = find(a); // b = find(b); // if (a == b) { // valid[a] = 1; // return; // } // id[b] = a; // valid[a] |= v | valid[b]; // } // }; // int main() { // int n, m, q; cin >> n >> m >> q; // vector<ti> edges; // vi A, B, W; // rep(i, 0, m) { // int a, b, c; cin >> a >> b >> c; // A.pb(a); // B.pb(b); // W.pb(c); // edges.pb({c, a, b}); // } // init(n, m, A, B, W); // sort(all(edges)); // while(q--) { // int a, b; cin >> a >> b; // UF uf(n); // int ans = -1; // for (auto &[c, u, v]: edges) { // // debug(c, u, v); // uf.join(u, v); // if (uf.find(a) == uf.find(b) && uf.valid[uf.find(a)]) { // ans = c; // break; // } // } // cout << ans << " " << getMinimumFuelCapacity(a, b) << nl; // assert(ans == getMinimumFuelCapacity(a, b)); // } // }
#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...