結果
問題 | No.1479 Matrix Eraser |
ユーザー |
![]() |
提出日時 | 2024-05-24 09:32:57 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 406 ms / 3,000 ms |
コード長 | 3,681 bytes |
コンパイル時間 | 2,597 ms |
コンパイル使用メモリ | 234,144 KB |
最終ジャッジ日時 | 2025-02-21 16:32:28 |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 39 |
ソースコード
#include <bits/stdc++.h>using namespace std;using ll = long long;const int INF = 1e9 + 10;const ll INFL = 4e18;template <typename Cap>struct max_flow {max_flow(int n) {this->n = n;G = vector<vector<tuple<int, int, Cap>>>(n);}void add_edge(int u, int v, Cap c) {G[u].push_back(make_tuple(v, G[v].size(), c));G[v].push_back(make_tuple(u, (int)G[u].size() - 1, 0));}Cap get_max_flow(int start, int goal) {Cap ret = 0;while (true) {vector<int> dst = calculate_distance(start);if (dst[goal] < 0) {return ret;}vector<int> removed(n, 0);while (true) {Cap add = flowing(start, goal, numeric_limits<Cap>::max(), removed, dst);if (add == 0) {break;}ret += add;}}return ret;}private:int n;vector<vector<tuple<int, int, Cap>>> G;vector<int> calculate_distance(int start) {vector<int> dst(n, -1);dst[start] = 0;queue<int> que;que.push(start);while (!que.empty()) {int now = que.front();que.pop();for (auto [nxt, _, cap] : G[now]) {if (cap > 0 && dst[nxt] == -1) {dst[nxt] = dst[now] + 1;que.push(nxt);}}}return dst;}Cap flowing(int now, int goal, Cap limit, vector<int> &removed, vector<int> &dst) {if (now == goal) {return limit;}while (removed[now] < (int)G[now].size()) {auto [nxt, rev, cap] = G[now][removed[now]];if (cap > 0 && dst[now] < dst[nxt]) {Cap flow = flowing(nxt, goal, min(limit, cap), removed, dst);if (flow > 0) {get<2>(G[now][removed[now]]) -= flow;get<2>(G[nxt][rev]) += flow;return flow;}}removed[now]++;}return 0;}};const int MX = 5e5 + 5;int main() {int H, W;cin >> H >> W;vector<vector<int>> A(H, vector<int>(W));for (int i = 0; i < H; i++) {for (int j = 0; j < W; j++) {cin >> A[i][j];}}vector<vector<pair<int, int>>> P(MX);for (int i = 0; i < H; i++) {for (int j = 0; j < W; j++) {P[A[i][j]].push_back({i, j});}}int ans = 0;for (int i = 1; i < MX; i++) {if (!P[i].empty()) {map<int, int> mp;{vector<int> idx;for (auto [x, y] : P[i]) {idx.push_back(x);idx.push_back(H + y);}idx.push_back(H + W);idx.push_back(H + W + 1);for (int x : set<int>(idx.begin(), idx.end())) {mp[x] = mp.size();}}max_flow<ll> mf(mp.size());set<int> used;for (auto [x, y] : P[i]) {mf.add_edge(mp[x], mp[H + y], 1);if (used.count(x) == 0) {mf.add_edge(mp[H + W], mp[x], 1);used.insert(x);}if (used.count(H + y) == 0) {mf.add_edge(mp[H + y], mp[H + W + 1], 1);used.insert(H + y);}}ans += mf.get_max_flow(mp[H + W], mp[H + W + 1]);}}cout << ans << endl;}