QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#561597#3952. Ice CreamLaVuna47AC ✓4ms3948kbC++178.3kb2024-09-13 01:00:252024-09-13 01:00:25

Judging History

This is the latest submission verdict.

  • [2024-09-13 01:00:25]
  • Judged
  • Verdict: AC
  • Time: 4ms
  • Memory: 3948kb
  • [2024-09-13 01:00:25]
  • Submitted

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
}

詳細信息

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'