제출 #951539

#제출 시각아이디문제언어결과실행 시간메모리
951539Nhoksocqt1자매 도시 (APIO20_swap)C++17
50 / 100
2013 ms25196 KiB
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define sz(x) int((x).size()) #define fi first #define se second typedef long long ll; typedef pair<int, int> ii; template<class X, class Y> inline bool maximize(X &x, const Y &y) {return (x < y ? x = y, 1 : 0);} template<class X, class Y> inline bool minimize(X &x, const Y &y) {return (x > y ? x = y, 1 : 0);} mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int Random(int l, int r) { return uniform_int_distribution<int>(l, r)(rng); } const int MAXN = 100005; struct Edge { int u, v, w; } edge[2 * MAXN]; ii minw[3]; vector<ii> adj[MAXN]; int pa[MAXN], wEdge[MAXN], cntLeaf[MAXN], maxw, numNode, numEdge; bool dp[1003][1003], dx[MAXN], check_sub1, check_sub2; void init(int _N, int _M, vector<int> _U, vector<int> _V, vector<int> _W) { numNode = _N, numEdge = _M; minw[0] = minw[1] = minw[2] = {1e9+7, -1}; check_sub2 = (numEdge + 1 == numNode); for (int i = 0; i < numEdge; ++i) { edge[i] = {_U[i], _V[i], _W[i]}; adj[edge[i].u].push_back(ii(edge[i].v, edge[i].w)); adj[edge[i].v].push_back(ii(edge[i].u, edge[i].w)); check_sub2 &= (edge[i].u == 0); maxw = max(maxw, edge[i].w); wEdge[edge[i].v] = edge[i].w; if(minw[0].fi > edge[i].w) { minw[2] = minw[1], minw[1] = minw[0]; minw[0] = {edge[i].w, edge[i].v}; } else if(minw[1].fi > edge[i].w) { minw[2] = minw[1]; minw[1] = {edge[i].w, edge[i].v}; } else if(minw[2].fi > edge[i].w) { minw[2] = {edge[i].w, edge[i].v}; } } check_sub1 = 1; for (int i = 0; i < numNode; ++i) check_sub1 &= (sz(adj[i]) <= 2); sort(edge, edge + numEdge, [](const Edge &a, const Edge &b) { return (a.w < b.w); }); } int sub2(int x, int y) { if(numNode <= 3) return -1; int res = max(wEdge[x], wEdge[y]), cnt(1 + (x == 0)); for (int k = 0; k < 3; ++k) { if(minw[k].se != x && minw[k].se != y) { if(--cnt == 0) { res = max(res, minw[k].fi); break; } } } return res; } int sub3(int x, int y) { int l(0), r(numEdge - 1), ans(-1); while(l <= r) { int mid = (l + r) >> 1; for (int i = 0; i < numNode; ++i) { for (int j = 0; j < numNode; ++j) dp[i][j] = 0; } queue<ii> qu; qu.push(ii(x, y)); dp[x][y] = 1; int xt(x), yt(y); bool check(0); while(sz(qu)) { int x(qu.front().fi), y(qu.front().se); qu.pop(); if(x == yt && y == xt) { check = 1; break; } for (int it = 0; it < sz(adj[x]); ++it) { int w(adj[x][it].fi), c(adj[x][it].se); if(c <= edge[mid].w && !dp[w][y] && w != y) { dp[w][y] = 1; qu.push(ii(w, y)); } } for (int it = 0; it < sz(adj[y]); ++it) { int w(adj[y][it].fi), c(adj[y][it].se); if(c <= edge[mid].w && !dp[x][w] && x != w) { dp[x][w] = 1; qu.push(ii(x, w)); } } } if(check) { ans = edge[mid].w; r = mid - 1; } else { l = mid + 1; } } return ans; } ii dfs(int u) { dx[u] = 1; cntLeaf[u] = 0; ii res = {sz(adj[u]), 1}; for (int it = 0; it < sz(adj[u]); ++it) { int v(adj[u][it].fi); if(!dx[v]) { pa[v] = u; ii tmp = dfs(v); res = {res.fi + tmp.fi, res.se + tmp.se}; cntLeaf[u] += cntLeaf[v]; } } if(cntLeaf[u] == 0) cntLeaf[u] = 1; return res; } int sub4(int x, int y) { int l(0), r(numEdge - 1), ans(-1); while(l <= r) { int mid = (l + r) >> 1; for (int i = 0; i < numNode; ++i) { adj[i].clear(); dx[i] = 0; } for (int i = 0; i <= mid; ++i) { int u(edge[i].u), v(edge[i].v); adj[u].push_back(ii(v, 0)); adj[v].push_back(ii(u, 0)); } pa[x] = -1; ii res = dfs(x); bool check(0); if(dx[y]) { int u(y); while(pa[u] != x) u = pa[u]; check = (res.fi / 2 >= res.se || cntLeaf[y] > 1 || cntLeaf[x] - cntLeaf[u] > 1 || cntLeaf[u] - cntLeaf[y] > 0); //cout << edge[mid].w << ' ' << res.fi << ' ' << res.se << ' ' << cntLeaf[x] << ' ' << cntLeaf[y] << ' ' << cntLeaf[u] << '\n'; } if(check) { ans = edge[mid].w; r = mid - 1; } else { l = mid + 1; } } return ans; } int getMinimumFuelCapacity(int x, int y) { if(check_sub1) return (numNode == numEdge) ? maxw : -1; if(check_sub2) return sub2(x, y); if(numNode <= 1000) return sub3(x, y); return sub4(x, y); } #ifdef Nhoksocqt1 int main(void) { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); #define TASK "swap" if(fopen(TASK".inp", "r")) { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); } vector<int> _U, _V, _W; int _N, _M, _Q; cin >> _N >> _M >> _Q; _U.resize(_M), _V.resize(_M), _W.resize(_M); for (int i = 0; i < _M; ++i) { cin >> _U[i] >> _V[i] >> _W[i]; } init(_N, _M, _U, _V, _W); for (int t = 0; t < _Q; ++t) { int _X, _Y; cin >> _X >> _Y; cout << "MINIMUM FUEL CAPACITY " << _X << " TO " << _Y << ": " << getMinimumFuelCapacity(_X, _Y) << '\n'; } return 0; } #endif // Nhoksocqt1
#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...