QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#561597 | #3952. Ice Cream | LaVuna47 | AC ✓ | 4ms | 3948kb | C++17 | 8.3kb | 2024-09-13 01:00:25 | 2024-09-13 01:00:25 |
Judging History
answer
/** gnu specific **/
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
/** contains everything I need in std **/
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(S) ((int)S.size())
#define FOR(i, n) for(int i = 0; i < n; ++i)
#define RFOR(i, n) for(int i = n-1; i >= 0; --i)
#define output_vec(vec) { FOR(i_, sz(vec)) cout << vec[i_] << ' '; cout << '\n'; }
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<bool> vb;
typedef short si;
typedef unsigned long long ull;
typedef long double LD;
typedef pair<ull, ull> pull;
using namespace __gnu_pbds;
typedef tree<ll, null_type, less<>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
using namespace std;
#ifdef ONPC
mt19937 rnd(228);
#else
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif
#ifndef ATCODER_MAXFLOW_HPP
#define ATCODER_MAXFLOW_HPP 1
#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>
#ifndef ATCODER_INTERNAL_QUEUE_HPP
#define ATCODER_INTERNAL_QUEUE_HPP 1
#include <vector>
namespace atcoder {
namespace internal {
template <class T> struct simple_queue {
std::vector<T> payload;
int pos = 0;
void reserve(int n) { payload.reserve(n); }
int size() const { return int(payload.size()) - pos; }
bool empty() const { return pos == int(payload.size()); }
void push(const T& t) { payload.push_back(t); }
T& front() { return payload[pos]; }
void clear() {
payload.clear();
pos = 0;
}
void pop() { pos++; }
};
} // namespace internal
} // namespace atcoder
#endif // ATCODER_INTERNAL_QUEUE_HPP
namespace atcoder {
template <class Cap> struct mf_graph {
public:
mf_graph() : _n(0) {}
explicit mf_graph(int n) : _n(n), g(n) {}
int add_edge(int from, int to, Cap cap) {
assert(0 <= from && from < _n);
assert(0 <= to && to < _n);
assert(0 <= cap);
int m = int(pos.size());
pos.push_back({from, int(g[from].size())});
int from_id = int(g[from].size());
int to_id = int(g[to].size());
if (from == to) to_id++;
g[from].push_back(_edge{to, to_id, cap});
g[to].push_back(_edge{from, from_id, 0});
return m;
}
struct edge {
int from, to;
Cap cap, flow;
};
edge get_edge(int i) {
int m = int(pos.size());
assert(0 <= i && i < m);
auto _e = g[pos[i].first][pos[i].second];
auto _re = g[_e.to][_e.rev];
return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
}
std::vector<edge> edges() {
int m = int(pos.size());
std::vector<edge> result;
for (int i = 0; i < m; i++) {
result.push_back(get_edge(i));
}
return result;
}
void change_edge(int i, Cap new_cap, Cap new_flow) {
int m = int(pos.size());
assert(0 <= i && i < m);
assert(0 <= new_flow && new_flow <= new_cap);
auto& _e = g[pos[i].first][pos[i].second];
auto& _re = g[_e.to][_e.rev];
_e.cap = new_cap - new_flow;
_re.cap = new_flow;
}
Cap flow(int s, int t) {
return flow(s, t, std::numeric_limits<Cap>::max());
}
Cap flow(int s, int t, Cap flow_limit) {
assert(0 <= s && s < _n);
assert(0 <= t && t < _n);
assert(s != t);
std::vector<int> level(_n), iter(_n);
internal::simple_queue<int> que;
auto bfs = [&]() {
std::fill(level.begin(), level.end(), -1);
level[s] = 0;
que.clear();
que.push(s);
while (!que.empty()) {
int v = que.front();
que.pop();
for (auto e : g[v]) {
if (e.cap == 0 || level[e.to] >= 0) continue;
level[e.to] = level[v] + 1;
if (e.to == t) return;
que.push(e.to);
}
}
};
auto dfs = [&](auto self, int v, Cap up) {
if (v == s) return up;
Cap res = 0;
int level_v = level[v];
for (int& i = iter[v]; i < int(g[v].size()); i++) {
_edge& e = g[v][i];
if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
Cap d =
self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
if (d <= 0) continue;
g[v][i].cap += d;
g[e.to][e.rev].cap -= d;
res += d;
if (res == up) return res;
}
level[v] = _n;
return res;
};
Cap flow = 0;
while (flow < flow_limit) {
bfs();
if (level[t] == -1) break;
std::fill(iter.begin(), iter.end(), 0);
Cap f = dfs(dfs, t, flow_limit - flow);
if (!f) break;
flow += f;
}
return flow;
}
std::vector<bool> min_cut(int s) {
std::vector<bool> visited(_n);
internal::simple_queue<int> que;
que.push(s);
while (!que.empty()) {
int p = que.front();
que.pop();
visited[p] = true;
for (auto e : g[p]) {
if (e.cap && !visited[e.to]) {
visited[e.to] = true;
que.push(e.to);
}
}
}
return visited;
}
private:
int _n;
struct _edge {
int to, rev;
Cap cap;
};
std::vector<std::pair<int, int>> pos;
std::vector<std::vector<_edge>> g;
};
} // namespace atcoder
#endif // ATCODER_MAXFLOW_HPP
vector<vector<pii>> G;
ll N;
ll f, c, v;
bool is_ok(ll flow_limit)
{
atcoder::mf_graph<ll> flow_net(N+1);
FOR(i, N+1)
{
for(auto [to, cap]: G[i])
{
flow_net.add_edge(i, to, cap);
}
}
ll f1 = flow_net.flow(c, f, flow_limit);
ll f2 = flow_net.flow(v, f, flow_limit);
return f1 == flow_limit && f2 == flow_limit;
}
bool can_increase_by_half(ll flow_limit)
{
{
atcoder::mf_graph<ll> flow_net(N+1);
FOR(i, N+1)
{
for(auto [to, cap]: G[i])
{
flow_net.add_edge(i, to, cap);
}
}
ll f1 = flow_net.flow(c, f, flow_limit+1);
ll f2 = flow_net.flow(v, f, flow_limit);
if(!(f1 == flow_limit+1 && f2 == flow_limit))
return false;
}
{
atcoder::mf_graph<ll> flow_net(N+1);
FOR(i, N+1)
{
for(auto [to, cap]: G[i])
{
flow_net.add_edge(i, to, cap);
}
}
ll f1 = flow_net.flow(c, f, flow_limit);
ll f2 = flow_net.flow(v, f, flow_limit+1);
if(!(f1 == flow_limit && f2 == flow_limit+1))
return false;
}
return true;
}
int solve()
{
int m;
if(!(cin >> N >> m))
return 1;
cin >> f >> c >> v;
G = vector<vector<pii>>(N+1);
FOR(_, m)
{
int a, b, cap;
cin >> a >> b >> cap;
G[a].pb({b, cap});
G[b].pb({a, cap});
}
ll l = 0, r = 10000004;
while(r-l > 1)
{
int mid = (l+r)/2;
if(is_ok(mid))
l = mid;
else
r = mid;
}
if(is_ok(r))
l = r;
if(can_increase_by_half(l))
cout << 2*l+1 << '\n';
else
cout << 2*l << '\n';
return 0;
}
int32_t main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int TET = 1e9;
//cin >> TET;
for (int i = 1; i <= TET; i++)
{
if (solve())
{
break;
}
#ifdef ONPC
cout << "__________________________" << endl;
#endif
}
#ifdef ONPC
cerr << endl << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
#endif
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3604kb
input:
3 2 2 1 3 1 2 2 3 2 3
output:
4
result:
ok single line: '4'
Test #2:
score: 0
Accepted
time: 2ms
memory: 3732kb
input:
200 591 198 199 200 199 1 70 200 1 278 1 198 834 199 2 356 200 2 364 2 198 723 199 3 964 200 3 264 3 198 452 199 4 100 200 4 49 4 198 8 199 5 365 200 5 116 5 198 387 199 6 895 200 6 909 6 198 744 199 7 524 200 7 785 7 198 768 199 8 924 200 8 369 8 198 981 199 9 319 200 9 454 9 198 222 199 10 117 200...
output:
94382
result:
ok single line: '94382'
Test #3:
score: 0
Accepted
time: 2ms
memory: 3872kb
input:
200 591 198 199 200 199 1 2 200 1 144 1 198 894 199 2 934 200 2 399 2 198 244 199 3 762 200 3 926 3 198 947 199 4 313 200 4 366 4 198 532 199 5 185 200 5 496 5 198 766 199 6 474 200 6 530 6 198 160 199 7 770 200 7 837 7 198 387 199 8 634 200 8 452 8 198 169 199 9 573 200 9 680 9 198 596 199 10 259 2...
output:
90933
result:
ok single line: '90933'
Test #4:
score: 0
Accepted
time: 2ms
memory: 3948kb
input:
200 591 198 199 200 199 1 212 200 1 91 1 198 182 199 2 770 200 2 108 2 198 331 199 3 98 200 3 526 3 198 246 199 4 605 200 4 569 4 198 543 199 5 90 200 5 804 5 198 965 199 6 179 200 6 324 6 198 328 199 7 720 200 7 969 7 198 911 199 8 868 200 8 52 8 198 801 199 9 223 200 9 257 9 198 856 199 10 868 200...
output:
91168
result:
ok single line: '91168'
Test #5:
score: 0
Accepted
time: 2ms
memory: 3868kb
input:
200 591 198 199 200 199 1 839 200 1 741 1 198 292 199 2 935 200 2 717 2 198 893 199 3 969 200 3 630 3 198 998 199 4 453 200 4 675 4 198 202 199 5 281 200 5 639 5 198 426 199 6 147 200 6 586 6 198 844 199 7 299 200 7 225 7 198 900 199 8 244 200 8 406 8 198 295 199 9 214 200 9 140 9 198 617 199 10 510...
output:
89398
result:
ok single line: '89398'
Test #6:
score: 0
Accepted
time: 0ms
memory: 3592kb
input:
4 3 1 2 3 1 4 3 2 4 2 3 4 2
output:
3
result:
ok single line: '3'
Test #7:
score: 0
Accepted
time: 3ms
memory: 3932kb
input:
200 1000 1 2 3 14 56 834 72 73 723 193 53 452 20 10 8 73 24 387 179 182 744 105 157 768 185 74 981 64 91 222 24 175 229 174 142 254 118 90 546 122 112 474 13 140 397 86 55 314 92 52 85 64 65 608 157 88 2 120 177 159 139 134 592 75 127 526 185 88 775 180 174 129 44 188 87 129 44 926 187 101 235 40 3 ...
output:
3833
result:
ok single line: '3833'
Test #8:
score: 0
Accepted
time: 3ms
memory: 3732kb
input:
200 1000 1 2 3 1 29 894 187 80 244 153 186 947 63 74 532 37 100 766 95 106 160 154 168 387 127 91 169 115 136 596 52 179 525 98 159 461 112 158 415 4 78 189 77 188 311 3 144 924 15 152 670 47 102 424 152 95 999 168 39 640 192 143 111 108 90 52 153 172 288 118 136 551 179 191 699 129 155 211 154 179 ...
output:
4428
result:
ok single line: '4428'
Test #9:
score: 0
Accepted
time: 4ms
memory: 3708kb
input:
200 1000 1 2 3 43 19 182 154 22 331 20 106 246 121 114 543 18 161 965 36 65 328 144 194 911 174 11 801 45 52 856 174 179 762 177 185 462 144 79 388 197 105 185 81 194 538 20 12 82 130 85 372 112 169 87 179 73 937 196 31 48 60 92 537 165 36 663 51 15 886 133 197 878 133 82 71 143 148 457 89 170 982 4...
output:
5868
result:
ok single line: '5868'
Test #10:
score: 0
Accepted
time: 3ms
memory: 3788kb
input:
200 1000 1 2 3 168 149 292 187 144 893 194 126 998 91 135 202 57 128 426 30 118 844 60 45 900 49 82 295 43 28 617 102 17 836 189 171 840 158 95 490 158 92 236 85 80 960 145 43 828 154 164 524 114 12 776 8 187 289 109 57 454 30 174 23 181 161 89 144 176 35 184 113 54 118 128 564 124 16 639 31 151 3 1...
output:
3900
result:
ok single line: '3900'