結果
問題 | No.1615 Double Down |
ユーザー |
![]() |
提出日時 | 2021-08-17 02:28:49 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,120 bytes |
コンパイル時間 | 1,169 ms |
コンパイル使用メモリ | 88,888 KB |
最終ジャッジ日時 | 2025-01-23 22:41:14 |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 32 TLE * 22 |
ソースコード
#line 1 "combinatorial_opt/test/mcf_costscaling.yuki1615.test.cpp"#define PROBLEM "https://yukicoder.me/problems/no/1615"#line 2 "data_structure/light_forward_list.hpp"#include <vector>// CUT begin// Simple forward_list for MLE-sensitive situations// Verify: <http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_D>template <typename T> struct light_forward_list {static std::vector<unsigned> ptr;static std::vector<T> val;unsigned head;light_forward_list() : head(0) {}void push_front(T x) {ptr.push_back(head), val.push_back(x);head = ptr.size() - 1;}struct iterator {unsigned p;iterator operator++() { return {p = ptr[p]}; }T &operator*() { return val[p]; }bool operator!=(const iterator &rhs) { return p != rhs.p; }};iterator begin() { return {head}; }iterator end() { return {0}; }};template <typename T> std::vector<unsigned> light_forward_list<T>::ptr = {0};template <typename T> std::vector<T> light_forward_list<T>::val = {T()};#line 3 "combinatorial_opt/mcf_costscaling.hpp"#include <cassert>#include <deque>#include <limits>// Cost scaling// https://people.orie.cornell.edu/dpw/orie633/// Implementation idea: https://yukicoder.me/submissions/680169template <class Cap, class Cost> struct mcf_costscaling {mcf_costscaling() = default;mcf_costscaling(int n) : _n(n), to(n), b(n), p(n) {static_assert(std::numeric_limits<Cap>::max() > 0, "max() must be greater than 0");}int _n;std::vector<Cap> cap;std::vector<Cost> cost;std::vector<int> opposite;std::vector<light_forward_list<int>> to;std::vector<Cap> b;std::vector<Cost> p;void add_edge(int from_, int to_, Cap cap_, Cost cost_) {assert(0 <= from_ && from_ < _n);assert(0 <= to_ && to_ < _n);assert(0 <= cap_);assert(0 <= cost_);cost_ *= (_n + 1);int e = int(cap.size());to[from_].push_front(e);cap.push_back(cap_);cost.push_back(cost_);opposite.push_back(to_);to[to_].push_front(e + 1);cap.push_back(0);cost.push_back(-cost_);opposite.push_back(from_);}void add_supply(int v, Cap supply) { b[v] += supply; }void add_demand(int v, Cap demand) { add_supply(v, -demand); }Cost flow(int SCALING = 1) {Cost eps = 1;for (const auto c : cost) {while (eps <= -c) eps <<= SCALING;}for (; eps >>= SCALING;) {for (int e = 0; e < int(cap.size()); e += 2) {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;} else if (cap[e ^ 1] and cp_ij > 0) {b[i] += cap[e ^ 1], b[j] -= cap[e ^ 1], cap[e] += cap[e ^ 1], cap[e ^ 1] = 0;}}std::deque<int> q;for (int i = 0; i < _n; i++) {if (b[i] > 0) q.push_back(i);}while (q.size()) {const int i = q.front();q.pop_front();for (auto e : to[i]) { // Pushif (!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) q.push_back(j);b[i] -= f, b[j] += f, cap[e] -= f, cap[e ^ 1] += f;if (!b[i]) break;}if (b[i] > 0) { // Relabelbool 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;}q.push_back(i);}}}Cost ret = 0;for (int e = 0; e < int(cap.size()); e += 2) ret += cost[e] * cap[e ^ 1];return ret / (_n + 1);}};#line 3 "combinatorial_opt/test/mcf_costscaling.yuki1615.test.cpp"#include <iostream>using namespace std;int main() {int N, M, K, L;cin >> N >> M >> K >> L;mcf_costscaling<int, long long> mcf(N + M + 2);long long ret = 0;for (int l = 0; l < L; l++) {int x, y, z;cin >> x >> y >> z;x--, y--;mcf.add_supply(y + N, 1);mcf.add_demand(x, 1);mcf.add_edge(y + N, x, 1, 1LL << z);ret += 1LL << z;}const int gs = N + M, gt = gs + 1;for (int i = 0; i < N; i++) mcf.add_edge(gs, i, 1, 0);for (int j = 0; j < M; j++) mcf.add_edge(N + j, gt, 1, 0);mcf.add_edge(gs, gt, N + M, 0);mcf.add_supply(gs, N + M);mcf.add_demand(gt, N + M);cout << ret - mcf.flow(2) << '\n';}