結果
問題 | No.1615 Double Down |
ユーザー | hitonanode |
提出日時 | 2021-08-19 01:02:35 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 964 ms / 10,000 ms |
コード長 | 5,727 bytes |
コンパイル時間 | 966 ms |
コンパイル使用メモリ | 85,772 KB |
実行使用メモリ | 19,748 KB |
最終ジャッジ日時 | 2024-10-11 22:38:09 |
合計ジャッジ時間 | 23,285 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 493 ms
9,056 KB |
testcase_01 | AC | 514 ms
9,056 KB |
testcase_02 | AC | 512 ms
12,488 KB |
testcase_03 | AC | 663 ms
12,488 KB |
testcase_04 | AC | 493 ms
12,280 KB |
testcase_05 | AC | 497 ms
12,288 KB |
testcase_06 | AC | 702 ms
19,748 KB |
testcase_07 | AC | 709 ms
15,552 KB |
testcase_08 | AC | 662 ms
15,436 KB |
testcase_09 | AC | 895 ms
12,532 KB |
testcase_10 | AC | 791 ms
12,528 KB |
testcase_11 | AC | 857 ms
12,524 KB |
testcase_12 | AC | 416 ms
14,688 KB |
testcase_13 | AC | 629 ms
14,592 KB |
testcase_14 | AC | 579 ms
18,884 KB |
testcase_15 | AC | 361 ms
15,716 KB |
testcase_16 | AC | 341 ms
15,724 KB |
testcase_17 | AC | 331 ms
15,720 KB |
testcase_18 | AC | 863 ms
12,404 KB |
testcase_19 | AC | 798 ms
12,524 KB |
testcase_20 | AC | 787 ms
12,528 KB |
testcase_21 | AC | 850 ms
13,272 KB |
testcase_22 | AC | 961 ms
12,652 KB |
testcase_23 | AC | 863 ms
12,404 KB |
testcase_24 | AC | 964 ms
16,628 KB |
testcase_25 | AC | 878 ms
12,532 KB |
testcase_26 | AC | 883 ms
12,284 KB |
testcase_27 | AC | 75 ms
5,248 KB |
testcase_28 | AC | 101 ms
5,248 KB |
testcase_29 | AC | 137 ms
6,160 KB |
testcase_30 | AC | 173 ms
6,292 KB |
testcase_31 | AC | 164 ms
6,188 KB |
testcase_32 | AC | 226 ms
6,192 KB |
testcase_33 | AC | 310 ms
7,328 KB |
testcase_34 | AC | 268 ms
7,336 KB |
testcase_35 | AC | 224 ms
7,080 KB |
testcase_36 | AC | 6 ms
5,248 KB |
testcase_37 | AC | 6 ms
5,248 KB |
testcase_38 | AC | 9 ms
5,248 KB |
testcase_39 | AC | 6 ms
5,248 KB |
testcase_40 | AC | 7 ms
5,248 KB |
testcase_41 | AC | 8 ms
5,248 KB |
testcase_42 | AC | 12 ms
5,248 KB |
testcase_43 | AC | 14 ms
5,248 KB |
testcase_44 | AC | 11 ms
5,248 KB |
testcase_45 | AC | 2 ms
5,248 KB |
testcase_46 | AC | 2 ms
5,248 KB |
testcase_47 | AC | 2 ms
5,248 KB |
testcase_48 | AC | 2 ms
5,248 KB |
testcase_49 | AC | 2 ms
5,248 KB |
testcase_50 | AC | 2 ms
5,248 KB |
testcase_51 | AC | 2 ms
5,248 KB |
testcase_52 | AC | 2 ms
5,248 KB |
testcase_53 | AC | 2 ms
5,248 KB |
testcase_54 | AC | 2 ms
5,248 KB |
testcase_55 | AC | 2 ms
5,248 KB |
testcase_56 | AC | 2 ms
5,248 KB |
ソースコード
#line 1 "combinatorial_opt/test/mcf_costscaling.yuki1615.test.cpp" #define PROBLEM "https://yukicoder.me/problems/no/1615" #line 2 "combinatorial_opt/mcf_costscaling.hpp" #include <cassert> #include <vector> // Cost scaling // https://people.orie.cornell.edu/dpw/orie633/ template <class Cap, class Cost, int SCALING = 1, int REFINEMENT_ITER = 20> struct mcf_costscaling { mcf_costscaling() = default; mcf_costscaling(int n) : _n(n), to(n), b(n), p(n) {} int _n; std::vector<Cap> cap; std::vector<Cost> cost; std::vector<int> opposite; std::vector<std::vector<int>> to; std::vector<Cap> b; std::vector<Cost> p; int add_edge(int from_, int to_, Cap cap_, Cost cost_) { assert(0 <= from_ and from_ < _n); assert(0 <= to_ and to_ < _n); assert(0 <= cap_); cost_ *= (_n + 1); const int e = int(cap.size()); to[from_].push_back(e); cap.push_back(cap_); cost.push_back(cost_); opposite.push_back(to_); to[to_].push_back(e + 1); cap.push_back(0); cost.push_back(-cost_); opposite.push_back(from_); return e / 2; } void add_supply(int v, Cap supply) { b[v] += supply; } void add_demand(int v, Cap demand) { add_supply(v, -demand); } template <typename RetCost = Cost> RetCost solve() { Cost eps = 1; std::vector<int> que; for (const auto c : cost) { while (eps <= -c) eps <<= SCALING; } for (; eps >>= SCALING;) { auto no_admissible_cycle = [&]() -> bool { for (int i = 0; i < _n; i++) { if (b[i]) return false; } std::vector<Cost> pp = p; for (int iter = 0; iter < REFINEMENT_ITER; iter++) { bool flg = false; for (int e = 0; e < int(cap.size()); e++) { if (!cap[e]) continue; int i = opposite[e ^ 1], j = opposite[e]; if (pp[j] > pp[i] + cost[e] + eps) pp[j] = pp[i] + cost[e] + eps, flg = true; } if (!flg) return p = pp, true; } return false; }; if (no_admissible_cycle()) continue; // Refine for (int e = 0; e < int(cap.size()); e++) { const int i = opposite[e ^ 1], j = opposite[e]; const Cost cp_ij = cost[e] + p[i] - p[j]; if (cap[e] and cp_ij < 0) b[i] -= cap[e], b[j] += cap[e], cap[e ^ 1] += cap[e], cap[e] = 0; } que.clear(); int qh = 0; for (int i = 0; i < _n; i++) { if (b[i] > 0) que.push_back(i); } std::vector<int> iters(_n); while (qh < int(que.size())) { const int i = que[qh++]; for (; iters[i] < int(to[i].size()) and b[i]; ++iters[i]) { // Push int e = to[i][iters[i]]; if (!cap[e]) continue; int j = opposite[e]; Cost cp_ij = cost[e] + p[i] - p[j]; if (cp_ij >= 0) continue; Cap f = b[i] > cap[e] ? cap[e] : b[i]; if (b[j] <= 0 and b[j] + f > 0) que.push_back(j); b[i] -= f, b[j] += f, cap[e] -= f, cap[e ^ 1] += f; } if (b[i] > 0) { // Relabel bool flg = false; for (int e : to[i]) { if (!cap[e]) continue; Cost x = p[opposite[e]] - cost[e] - eps; if (!flg or x > p[i]) flg = true, p[i] = x; } que.push_back(i), iters[i] = 0; } } } RetCost ret = 0; for (int e = 0; e < int(cap.size()); e += 2) ret += RetCost(cost[e]) * cap[e ^ 1]; return ret / (_n + 1); } std::vector<Cost> potential() const { std::vector<Cost> ret = p, c0 = cost; for (auto &x : ret) x /= (_n + 1); for (auto &x : c0) x /= (_n + 1); while (true) { bool flg = false; for (int i = 0; i < _n; i++) { for (const auto e : to[i]) { if (!cap[e]) continue; int j = opposite[e]; auto y = ret[i] + c0[e]; if (ret[j] > y) ret[j] = y, flg = true; } } if (!flg) break; } return ret; } struct edge { int from, to; Cap cap, flow; Cost cost; }; edge get_edge(int e) const { int m = cap.size() / 2; assert(e >= 0 and e < m); return {opposite[e * 2 + 1], opposite[e * 2], cap[e * 2] + cap[e * 2 + 1], cap[e * 2 + 1], cost[e * 2] / (_n + 1)}; } std::vector<edge> edges() const { int m = cap.size() / 2; std::vector<edge> result(m); for (int i = 0; i < m; i++) result[i] = get_edge(i); return result; } }; #line 3 "combinatorial_opt/test/mcf_costscaling.yuki1615.test.cpp" #include <iostream> using namespace std; int main() { cin.tie(nullptr), ios::sync_with_stdio(false); int N, M, K, L; cin >> N >> M >> K >> L; mcf_costscaling<int, long long, 2, 6> mcf(N + M + 1); for (int l = 0; l < L; l++) { int x, y, z; cin >> x >> y >> z; mcf.add_edge(x, y + N, 1, -(1LL << z)); } const int gs = 0; for (int i = 0; i < N; i++) mcf.add_edge(gs, i + 1, 1, 0); for (int j = 0; j < M; j++) mcf.add_edge(N + j + 1, gs, 1, 0); cout << -mcf.solve() << '\n'; }