結果

問題 No.1479 Matrix Eraser
ユーザー jupirojupiro
提出日時 2021-04-16 20:38:51
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 3,804 bytes
コンパイル時間 1,606 ms
コンパイル使用メモリ 133,272 KB
実行使用メモリ 25,060 KB
最終ジャッジ日時 2024-07-02 23:05:00
合計ジャッジ時間 9,739 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 6 ms
21,980 KB
testcase_01 AC 5 ms
14,896 KB
testcase_02 AC 6 ms
14,900 KB
testcase_03 AC 6 ms
14,948 KB
testcase_04 AC 6 ms
15,020 KB
testcase_05 AC 6 ms
15,040 KB
testcase_06 AC 8 ms
14,932 KB
testcase_07 AC 1,044 ms
15,848 KB
testcase_08 AC 1,914 ms
16,524 KB
testcase_09 TLE -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
testcase_31 -- -
testcase_32 -- -
testcase_33 -- -
testcase_34 -- -
testcase_35 -- -
testcase_36 -- -
testcase_37 -- -
testcase_38 -- -
testcase_39 -- -
testcase_40 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <utility>
#include <tuple>
#include <cmath>
#include <numeric>
#include <set>
#include <map>
#include <array>
#include <complex>
#include <iomanip>
#include <cassert>
#include <random>
using ll = long long;
using std::cin;
using std::cout;
using std::endl;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
const int inf = (int)1e9 + 7;
const long long INF = 1LL << 60;


namespace KKT89
{
  template<typename T>
  struct Dinic {
      struct edge {
          int to;
          T cap;
          int rev;
          bool isrev;
          int idx;
          edge(int _to, T _cap, int _rev, bool _isrev, int _idx) :to(_to), cap(_cap), rev(_rev), isrev(_isrev), idx(_idx) {}
      };
      std::vector<std::vector<edge>> g;
      std::vector<int> min_cost, iter;
      T INF;
      Dinic(int n, T INF) :g(n), INF(INF) {}

      void add_edge(int from, int to, T cap, int idx = -1) {
          g[from].emplace_back(to, cap, (int)g[to].size(), false, idx);
          g[to].emplace_back(from, 0, (int)g[from].size() - 1, true, idx);
      }

      bool bfs(int s, int t) {
          min_cost.assign(g.size(), -1);
          std::queue<int> q;
          q.emplace(s);
          min_cost[s] = 0;
          while (!q.empty() && min_cost[t] == -1) {
              int cur = q.front();
              q.pop();
              for (auto& e : g[cur]) {
                  if (e.cap > 0 && min_cost[e.to] == -1) {
                      min_cost[e.to] = min_cost[cur] + 1;
                      q.push(e.to);
                  }
              }
          }
          return min_cost[t] != -1;
      }

      T dfs(int idx, const int t, T flow) {
          if (idx == t) return flow;
          for (int& i = iter[idx]; i < (int)g[idx].size(); i++) {
              edge& e = g[idx][i];
              if (e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
                  T d = dfs(e.to, t, std::min(flow, e.cap));
                  if (d > 0) {
                      e.cap -= d;
                      g[e.to][e.rev].cap += d;
                      return d;
                  }
              }
          }
          return 0;
      }

      T max_flow(int s, int t) {
          T flow = 0;
          while (bfs(s, t)) {
              iter.assign(g.size(), 0);
              T f = 0;
              while ((f = dfs(s, t, INF)) > 0) flow += f;
          }
          return flow;
      }

      void output() {
          for(int i = 0; i < (int)g.size(); i++) {
            for(auto &e : g[i]) {
              if(e.isrev) continue;
              auto &rev_e = g[e.to][e.rev];
              cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
            }
          }
      }
  };
}
void solve()
{
  int H, W; cin >> H >> W;
  const int N = 500000;
  std::vector<std::vector<std::pair<int, int>>> vp(N + 1);
  for (int i = 0; i < H; ++i)
  {
    for (int j = 0; j < W; ++j)
    {
      int x; cin >> x;
      vp[x].emplace_back(i, j);
    }
  }
  int res = 0;
  for (int i = 1; i <= N; ++i)
  {
    if(vp[i].empty())
      continue;
    KKT89::Dinic g(H + W + 2, inf);
    const int s = H + W;
    const int t = s + 1;
    for(const auto &[h, w] : vp[i])
    {
      g.add_edge(h, H + w, 1);
    }
    for (int i = 0; i < H; ++i)
    {
      g.add_edge(s, i, 1);
    }
    for (int i = 0; i < W; ++i)
    {
      g.add_edge(H + i, t, 1);
    }
    res += g.max_flow(s, t);
  }
  cout << res << "\n";
}
int main()
{
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  int kkt = 1;
  //cin >> kkt;
  while(kkt--)
    solve();
  return 0;
}
0