Submission #367659

#TimeUsernameProblemLanguageResultExecution timeMemory
367659534351Aesthetic (NOI20_aesthetic)C++17
13 / 100
2085 ms96732 KiB
#include <bits/stdc++.h> using namespace std; template<class T, class U> void ckmin(T &a, U b) { if (a > b) a = b; } template<class T, class U> void ckmax(T &a, U b) { if (a < b) a = b; } #define MP make_pair #define PB push_back #define LB lower_bound #define UB upper_bound #define fi first #define se second #define SZ(x) ((int) (x).size()) #define ALL(x) (x).begin(), (x).end() #define FOR(i, a, b) for (auto i = (a); i < (b); i++) #define FORD(i, a, b) for (auto i = (a) - 1; i >= (b); i--) const int MAXN = 3e5 + 13; const long long LLINF = 3e18; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef vector<int> vi; typedef vector<ll> vl; typedef vector<pii> vpi; typedef vector<pll> vpl; typedef pair<pll, int> ppi; int N, M, C, T; vector<ppi> edge[MAXN]; ll dist[2][MAXN]; ll D; int st[MAXN], ft[MAXN], parent[MAXN], flagged[MAXN]; bitset<MAXN> seen; vi bcc[MAXN]; unordered_set<int> blocks[MAXN], bridges[MAXN]; vpi edges; void dijkstra(int u) { bool b = (u > 0); fill(dist[b], dist[b] + N + 1, LLINF); dist[b][u] = 0; priority_queue<pll, vector<pll>, greater<pll> > pq; pq.push({0, u}); while(!pq.empty()) { ll d = pq.top().fi; int u = pq.top().se; pq.pop(); if (d != dist[b][u]) continue; for (auto e : edge[u]) { int v = e.se; ll nd = d + e.fi.fi; if (nd < dist[b][v]) { dist[b][v] = nd; pq.push({nd, v}); } } } } void dfs(int u, int p) { st[u] = T; ft[u] = T; T++; seen[u] = true; for (auto e : edge[u]) { int v = e.se; ll d = e.fi.fi; if (dist[0][u] + d + dist[1][v] >= D && dist[1][u] + d + dist[0][v] >= D) continue; //oh no it is part of a path shorter than D, so the edge actually exists. if (v == p) continue; if (seen[v]) { if (st[v] > st[u]) continue; edges.PB({u, v}); ckmin(ft[u], st[v]); continue; } // cerr << u << ' ' << v << endl; // cerr << (bool) (dist[0][u] + d + dist[1][v] < D) << ' ' << (bool) (dist[1][u] + d + dist[0][v] < D) << endl; edges.PB({u, v}); parent[v] = u; dfs(v, u); ckmin(ft[u], ft[v]); if (ft[v] >= st[u]) { while(!edges.empty()) { pii p = edges.back(); edges.pop_back(); bcc[C].PB(p.fi); bcc[C].PB(p.se); if (p == MP(u, v)) break; } C++; } } } bool check() { //can you make the dist >D? //ans is YES if there's a bridge & this thing extends dist by more than D. T = 0; fill(parent, parent + N, N); fill(st, st + N, 0); fill(ft, ft + N, 0); fill(flagged, flagged + N, 0); seen.reset(); FOR(i, 0, C) bcc[i].clear(); C = 0; FOR(i, 0, N) { if (seen[i]) continue; if (i == N - 1) return false; dfs(i, N); } for (int i = N - 1; i != 0; i = parent[i]) { flagged[i]++; } FOR(i, 0, C) { int u = -1, v = -1; for (int x : bcc[i]) { if (u == x || v == x) continue; if (u == -1) { u = x; } else if (v == -1) { v = x; } else { u = -1; break; } } if (u == -1) continue; if (u == parent[v]) flagged[v]++; if (v == parent[u]) flagged[u]++; } FOR(u, 0, N) { for (auto e : edge[u]) { int v = e.se; ll mx = e.fi.se; if (u != parent[v]) continue; if (flagged[v] != 2) continue; // cerr << u << ' ' << v << ' ' << mx << ' ' << dist[0][u] + mx + dist[1][v] << ' ' << dist[1][u] + mx + dist[0][v] << endl; if (dist[0][u] + mx + dist[1][v] >= D && dist[1][u] + mx + dist[0][v] >= D) return true; } } return false; //now just check if there's something we can extend that is a bridge. } int32_t main() { cout << fixed << setprecision(12); cerr << fixed << setprecision(4); ios_base::sync_with_stdio(false); cin.tie(0); cin >> N >> M; vector<array<int, 3> > eds; FOR(i, 0, M) { int a, b, w; cin >> a >> b >> w; a--; b--; if (a == b) continue; eds.PB({a, b, w}); } reverse(ALL(eds)); int mx = 0; for (auto e : eds) { int a = e[0], b = e[1], w = e[2]; edge[a].PB({{w, w + mx}, b}); edge[b].PB({{w, w + mx}, a}); ckmax(mx, w); } dijkstra(0); dijkstra(N - 1); ll lo = dist[0][N - 1], hi = 1e15; // cerr << mx << ' '<< lo << ' ' << hi << endl; while(hi > lo) { D = (hi + lo + 1) >> 1; if (check()) lo = D; else hi = D - 1; } cout << lo << '\n'; return 0; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...