Submission #292355

#TimeUsernameProblemLanguageResultExecution timeMemory
292355luciocfSwapping Cities (APIO20_swap)C++14
100 / 100
314 ms22264 KiB
#include <bits/stdc++.h> #include "swap.h" #define ff first #define ss second using namespace std; typedef pair<int, int> pii; const int maxn = 2e5+10; const int inf = 1e9+10; int n; int mn3[maxn]; int ans[maxn]; int D[maxn], par[maxn]; bool mark[maxn]; vector<pii> grafo[maxn]; struct Edge { int u, v, w; } edge[maxn]; struct DSU { int pai[maxn], peso[maxn], nivel[maxn], val[maxn], tt[maxn]; void init(int n) { for (int i = 1; i <= n; i++) { pai[i] = i, peso[i] = 1, nivel[i] = 0; if (grafo[i].size() >= 3) val[i] = mn3[i]; else val[i] = inf; } } int Find(int x) { if (pai[x] == x) return x; return Find(pai[x]); } void Join(int x, int y, int t) { x = Find(x), y = Find(y); if (x == y) return; if (peso[x] < peso[y]) swap(x, y); pai[y] = x, peso[x] += peso[y], tt[y] = t; } void dfs(int u) { if (u == Find(u)) { nivel[u] = 1; return; } if (!nivel[pai[u]]) dfs(pai[u]); nivel[u] = nivel[pai[u]]+1; } void upd(int u) { int v = u; int mx = 0; while (true) { val[v] = min(val[v], max(mn3[u], mx)); if (pai[v] == v) return; mx = max(mx, tt[v]); v = pai[v]; } } int get(int u) { int v = u, ans = inf, mx = 0; while (true) { ans = min(ans, max(mx, val[v])); if (v == pai[v]) return ans; mx = max(mx, tt[v]); v = pai[v]; } } int get_mx(int u, int v) { int ans = 0; while (u != v) { if (nivel[u] > nivel[v]) { ans = max(ans, tt[u]); u = pai[u]; } else { ans = max(ans, tt[v]); v = pai[v]; } } return ans; } } dsu; void init(int N, int m, vector<int> U, vector<int> V, vector<int> W) { n = N; for (int i = 0; i < m; i++) { grafo[U[i]+1].push_back({V[i]+1, W[i]}); grafo[V[i]+1].push_back({U[i]+1, W[i]}); edge[i+1] = {U[i]+1, V[i]+1, W[i]}; } sort(edge+1, edge+m+1, [&] (Edge a, Edge b) {return a.w < b.w;}); for (int i = 1; i <= n; i++) { sort(grafo[i].begin(), grafo[i].end(), [&] (pii a, pii b) {return a.ss < b.ss;}); if (grafo[i].size() <= 2) mn3[i] = inf; else mn3[i] = grafo[i][2].ss; } dsu.init(n); for (int i = 1; i <= m; i++) { if (dsu.Find(edge[i].u) == dsu.Find(edge[i].v)) { mn3[edge[i].u] = min(mn3[edge[i].u], edge[i].w); mn3[edge[i].v] = min(mn3[edge[i].v], edge[i].w); } dsu.Join(edge[i].u, edge[i].v, edge[i].w); } for (int i = 1; i <= n; i++) { if (mn3[i] != inf) dsu.upd(i); if (!dsu.nivel[i]) dsu.dfs(i); } } int getMinimumFuelCapacity(int u, int v) { u++, v++; if (u == v) return -1; if (min(dsu.get(u), dsu.get(v)) == inf) return -1; return max(min(dsu.get(u), dsu.get(v)), dsu.get_mx(u, v)); }
#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...