結果
問題 | No.1479 Matrix Eraser |
ユーザー |
|
提出日時 | 2023-01-26 22:27:58 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 131 ms / 3,000 ms |
コード長 | 2,472 bytes |
コンパイル時間 | 1,766 ms |
コンパイル使用メモリ | 201,828 KB |
最終ジャッジ日時 | 2025-02-10 07:07:24 |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 39 |
ソースコード
#include <bits/stdc++.h>using namespace std;#define fi first#define se second#define pb push_backusing vi = vector <int>;using ll = long long;using pii = pair <int, int>;//~ const ll mod = 998244353;const ll mod = 1e9 + 7;ll qpow(ll a, ll b, ll m = mod) { ll r = 1, t = a;for(; b; b /= 2) { if(b & 1) r = r * t % m; t = t * t % m; } return r; }const int N = 511;const int mxn = N * 2;const int mxm = N * N * 4;using Flow = int;const int MXL = 1e9;struct Flownet {int n, m;int fe[mxn];int ne[mxm];int ev[mxm];Flow f[mxm];void clear(int n) {this->n = n;fill(fe, fe + n + 1, 0);m = 1;}void add_(int x, int y, Flow flow) { // 添加一条边ne[++m] = fe[x];fe[x] = m;ev[m] = y;f[m] = flow;}void add1(int x, int y, Flow flow) { // 添加一条单向边和其反向边add_(x, y, flow);add_(y, x, 0);}int T;int arc[mxn], lev[mxn];Flow extend(int x, Flow flow) {if (x == T) return flow;Flow re = 0;for (int &e = arc[x]; e; e = ne[e]) if (f[e] && lev[ev[e]] == lev[x] + 1) {Flow t = extend(ev[e], min(flow - re, f[e]));if (t) {f[e] -= t;f[e ^ 1] += t;if ((re += t) == flow)break;}}if (!re) lev[x] = 0;return re;}int q[mxn], *qb, *qe;Flow dinic(int S, int T) {this->T = T;Flow re = 0;for (;;) {fill(lev, lev + n + 1, 0);copy(fe, fe + n + 1, arc);lev[S] = 1;qb = qe = q;*qe++ = S;while (qb != qe) {int x = *qb++;if (lev[T] && lev[x] + 1 >= lev[T])break;for (int e = fe[x]; e; e = ne[e]) if (f[e] && !lev[ev[e]]) {lev[ev[e]] = lev[x] + 1;*qe++ = ev[e];}}if (!lev[T]) break;re += extend(S, MXL);}return re;}}net;int vx[N], vy[N];const int M = 5e5 + 11;vector <pii> v[M];int main() {ios :: sync_with_stdio(false);int n, m; cin >> n >> m;for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++) {int x; cin >> x;v[x].pb({i, j});}int ans = 0;for(int i = 1; i < M; i ++) if(v[i].size()) {if(v[i].size() == 1) ans ++;else {int S = 0, T = n + m + 1;net.clear(T);memset(vx, 0, sizeof vx);memset(vy, 0, sizeof vy);for(auto [x, y] : v[i]) {net.add1(x, y + n, 1);vx[x] = 1; vy[y] = 1;}for(int x = 1; x <= n; x ++)if(vx[x]) net.add1(S, x, 1);for(int y = 1; y <= m; y ++)if(vy[y]) net.add1(y + n, T, 1);ans += net.dinic(S, T);}}cout << ans << '\n';}