結果
| 問題 |
No.957 植林
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-11-04 09:01:47 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 695 ms / 2,000 ms |
| コード長 | 3,684 bytes |
| コンパイル時間 | 1,592 ms |
| コンパイル使用メモリ | 96,256 KB |
| 最終ジャッジ日時 | 2025-01-15 19:41:12 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 45 |
ソースコード
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <limits>
template <class T>
std::vector<T> vec(int len, T elem) { return std::vector<T>(len, elem); }
template <class Cap, bool isDirect>
struct MaxFlow {
struct Edge {
int src, dst;
Cap cap;
Edge(int src, int dst, Cap cap)
: src(src), dst(dst), cap(cap){};
};
std::vector<Edge> edges;
std::vector<std::vector<int>> graph;
std::vector<int> dist, iter;
explicit MaxFlow(int n) : graph(n), dist(n), iter(n) {}
void span(int u, int v, Cap cap) {
graph[u].push_back(edges.size());
edges.emplace_back(u, v, cap);
graph[v].push_back(edges.size());
edges.emplace_back(v, u, (isDirect ? 0 : cap));
}
void bfs(int s) {
std::fill(dist.begin(), dist.end(), -1);
dist[s] = 0;
std::queue<int> que;
que.push(s);
while (!que.empty()) {
auto v = que.front();
que.pop();
for (auto eidx : graph[v]) {
const auto& edge = edges[eidx];
if (edge.cap > 0 && dist[edge.dst] == -1) {
dist[edge.dst] = dist[v] + 1;
que.push(edge.dst);
}
}
}
}
Cap dfs(int v, int g, Cap f) {
if (v == g) return f;
for (auto& itr = iter[v]; itr < (int)graph[v].size(); ++itr) {
auto eidx = graph[v][itr];
auto& edge = edges[eidx];
if (edge.cap > 0 && dist[v] < dist[edge.dst]) {
auto df = dfs(edge.dst, g, std::min(f, edge.cap));
if (df > 0) {
edge.cap -= df;
auto& redge = edges[eidx ^ 1];
redge.cap += df;
return df;
}
}
}
return 0;
}
Cap flow(int s, int g) {
const Cap INF = std::numeric_limits<Cap>::max();
Cap ret = 0;
while (true) {
bfs(s);
if (dist[g] < 0) return ret;
std::fill(iter.begin(), iter.end(), 0);
while (true) {
Cap f = dfs(s, g, INF);
if (f == 0) break;
ret += f;
}
}
}
};
using lint = long long;
void solve() {
int h, w;
std::cin >> h >> w;
auto gss = vec(h, vec(w, 0LL));
lint gsum = 0;
std::vector<lint> grsum(h, 0), gcsum(w, 0);
for (int i = 0; i < h; ++i) {
for (int j = 0; j < w; ++j) {
auto& g = gss[i][j];
std::cin >> g;
g *= 2;
gsum += g;
grsum[i] += g;
gcsum[j] += g;
}
}
std::vector<lint> rs(h), cs(w);
for (auto& r : rs) {
std::cin >> r;
r *= 2;
}
for (auto& c : cs) {
std::cin >> c;
c *= 2;
}
lint gain = gsum;
for (auto r : rs) gain += r;
for (auto c : cs) gain += c;
int s = h + w, g = s + 1;
MaxFlow<lint, true> mf(h + w + 2);
for (int i = 0; i < h; ++i) {
mf.span(s, i, grsum[i] / 2 + rs[i]);
mf.span(i, g, grsum[i]);
}
for (int j = 0; j < w; ++j) {
mf.span(s, j + h, gcsum[j] / 2 + cs[j]);
mf.span(j + h, g, gcsum[j]);
}
for (int i = 0; i < h; ++i) {
for (int j = 0; j < w; ++j) {
mf.span(i, j + h, gss[i][j] / 2);
mf.span(j + h, i, gss[i][j] / 2);
}
}
auto cost = mf.flow(s, g);
std::cout << (gain - cost) / 2 << "\n";
}
int main() {
std::cin.tie(nullptr);
std::ios::sync_with_stdio(false);
solve();
return 0;
}