結果
| 問題 | No.3668 Minimum Cut |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-08-27 13:07:46 |
| 言語 | C++23 (gcc 15.3.0 + boost 1.92.0) |
| 結果 |
AC
|
| 実行時間 | 1,058 ms / 2,000 ms |
| + 320µs | |
| コード長 | 2,686 bytes |
| 記録 | |
| コンパイル時間 | 2,555 ms |
| コンパイル使用メモリ | 360,724 KB |
| 実行使用メモリ | 6,400 KB |
| 最終ジャッジ日時 | 2026-09-04 22:55:29 |
| 合計ジャッジ時間 | 8,855 ms |
|
ジャッジサーバーID (参考情報) |
judge4_0 / judge3_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 39 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
template<typename T>
struct max_flow{
struct edge {
int from, to;
T cap, flow;
};
int N;
vector<edge> es;
max_flow(int _N) : N(_N) {}
void add_edge(int from, int to, T cap) {
es.emplace_back(edge{from, to, cap, 0});
}
T flow(int s, int t) {
assert(s != t);
unsigned long long total_flow = 0;
for (int l = 63; l >= 0; l--) {
while (1) {
vector<int> D(N, N);
vector<vector<int>> E(N);
for (auto e : es) {
if ((e.cap - e.flow) >> l) E[e.from].emplace_back(e.to);
if (e.flow >> l) E[e.to].emplace_back(e.from);
}
queue<int> Q;
Q.emplace(s);
D[s] = 0;
while (!Q.empty()) {
int v = Q.front(); Q.pop();
for (auto u : E[v]) if (D[u] > D[v] + 1) {
D[u] = D[v] + 1;
Q.emplace(u);
}
}
if (D[t] == N) break;
E.assign(N, {});
for (int i = 0; i < es.size(); i++) {
auto e = es[i];
if (((e.cap - e.flow) >> l) && D[e.from] + 1 == D[e.to]) E[e.from].emplace_back(i);
if ((e.flow >> l) && D[e.from] == D[e.to] + 1) E[e.to].emplace_back(- i - 1);
}
vector<int> idx(N);
iota(idx.begin(), idx.end(), 0);
sort(idx.begin(), idx.end(), [&](int i, int j) {return D[i] < D[j];});
while (1) {
vector<T> DP(N);
vector<int> P(N);
DP[s] = numeric_limits<T>::max();
for (auto v : idx) {
for (auto i : E[v]) {
if (i >= 0) {
if (DP[es[i].to] < min(DP[v], es[i].cap - es[i].flow)) {
DP[es[i].to] = min(DP[v], es[i].cap - es[i].flow);
P[es[i].to] = i;
}
}
else if (DP[es[- i - 1].from] < min(DP[v], es[- i - 1].flow)) {
DP[es[- i - 1].from] = min(DP[v], es[- i - 1].flow);
P[es[- i - 1].from] = i;
}
}
}
if (!DP[t]) break;
total_flow += DP[t];
int v = t;
while (v != s) {
int i = P[v];
if (i >= 0) {
v = es[i].from;
es[i].flow += DP[t];
}
else {
v = es[- i - 1].to;
es[- i - 1].flow -= DP[t];
}
}
}
}
}
return total_flow;
}
};
int main() {
int N, M, S, T;
cin >> N >> M >> S >> T;
S--; T--;
max_flow<long long> G(N);
while (M--) {
int u, v, c;
cin >> u >> v >> c;
u--; v--;
G.add_edge(u, v, c);
}
cout << G.flow(S, T) << endl;
}