Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- using ll = long long;
- using ld = long double;
- using ull = unsigned long long;
- using pii = pair<int, int>;
- using pll = pair<ll, ll>;
- using pld = pair<ld, ld>;
- #define fi first
- #define se second
- #define pb push_back
- #define pf push_front
- #define mp make_pair
- #define ins insert
- #define btpc __builtin_popcount
- #define btclz __builtin_clz
- #define sz(x) (int)(x.size());
- #define all(x) x.begin(), x.end()
- #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
- int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
- int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
- template<class X, class Y>
- bool minimize(X &x, const Y &y) {
- if (x > y)
- {
- x = y;
- return true;
- }
- return false;
- }
- template<class X, class Y>
- bool maximize(X &x, const Y &y) {
- if (x < y)
- {
- x = y;
- return true;
- }
- return false;
- }
- const int MOD = 1e9 + 7; //998244353
- template<class X, class Y>
- void add(X &x, const Y &y) {
- x = (x + y);
- if(x >= MOD) x -= MOD;
- }
- template<class X, class Y>
- void sub(X &x, const Y &y) {
- x = (x - y);
- if(x < 0) x += MOD;
- }
- /* Author : Le Ngoc Bao Anh, 11A5, LQD High School for Gifted Student*/
- const ll INF = 1e9;
- const int N = 100 + 10;
- struct Dinitz {
- struct Edges {
- int u, v;
- ll cap;
- Edges() : u(), v(), cap() {}
- Edges(int _u, int _v, ll _cap) : u(_u), v(_v), cap(_cap) {}
- };
- vector<vector<int>> g;
- vector<Edges> ed;
- vector<int> dist;
- vector<int> id;
- int S, T;
- int n;
- Dinitz() : ed(), n(), S(), T() {}
- Dinitz(int _n, int _S, int _T) {
- n = _n; S = _S; T = _T;
- g.resize(n);
- dist.resize(n);
- id.resize(n);
- for(int i = 0; i < n; i++) g[i].clear();
- ed = vector<Edges>();
- }
- void addEdge(int u, int v, ll cap) {
- g[u].pb((int)ed.size());
- ed.pb(Edges(u, v, cap));
- g[v].pb((int)ed.size());
- ed.pb(Edges(v, u, 0));
- }
- bool bfs() {
- for(int i = 0; i < n; i++) dist[i] = n + 5;
- queue<int> q;
- q.push(S); dist[S] = 0;
- while(!q.empty()) {
- int u = q.front(); q.pop();
- for(int i : g[u]) {
- Edges e = ed[i];
- if(!e.cap) continue;
- if(dist[e.v] <= dist[u] + 1) continue;
- dist[e.v] = dist[u] + 1;
- q.push(e.v);
- }
- }
- return dist[T] < n + 5;
- }
- ll dfs(int u, ll flow) {
- if(u == T || flow == 0) return flow;
- ll ans = 0;
- for(int &i = id[u]; i < (int)g[u].size(); i++) {
- Edges e = ed[g[u][i]];
- if(!e.cap) continue;
- if(dist[e.v] != dist[u] + 1) continue;
- ll f = dfs(e.v, min(flow, e.cap));
- flow -= f;
- ans += f;
- ed[g[u][i]].cap -= f;
- ed[g[u][i] ^ 1].cap += f;
- if(flow == 0) return ans;
- }
- return ans;
- }
- ll Flow() {
- ll ans = 0;
- while(bfs()) {
- for(int i = 0; i < n; i++) id[i] = 0;
- ans += dfs(S, INF * INF);
- }
- return ans;
- }
- bool check() {
- for(int i = 0; i < ed.size(); i++) {
- if(ed[i].u < S && ed[i].v < S) continue;
- int u = ed[i].u, v = ed[i].v;
- if(v == S) continue;
- if(u == T) continue;
- if(ed[i].cap) {
- return false;
- }
- }
- return true;
- };
- };
- char a[N][N];
- int ln[N][N][N];
- int hn[N][N][N];
- int lm[N][N][N];
- int hm[N][N][N];
- void solve() {
- int n, m;
- cin >> n >> m;
- for(int i = 1; i <= n; i++) {
- for(int j = 1; j <= m; j++) {
- cin >> a[i][j];
- }
- }
- int v = max(n, m);
- for(int i = 0; i <= m; i++) {
- for(int j = 0; j <= m; j++) {
- if(i + j > m) break;
- int r = m - i - j;
- for(int x = 0; x <= v; x++) {
- ln[i][j][x] = INF;
- hn[i][j][x] = 0;
- for(int d = 0; d <= r; d++) {
- if(abs(i + d - (j + (r - d))) <= x) {
- minimize(ln[i][j][x], d);
- maximize(hn[i][j][x], d);
- }
- }
- }
- }
- }
- for(int i = 0; i <= n; i++) {
- for(int j = 0; j <= n; j++) {
- if(i + j > n) break;
- int r = n - i - j;
- for(int x = 0; x <= v; x++) {
- lm[i][j][x] = INF;
- hm[i][j][x] = 0;
- for(int d = 0; d <= r; d++) {
- if(abs(i + d - (j + (r - d))) <= x) {
- minimize(lm[i][j][x], d);
- maximize(hm[i][j][x], d);
- }
- }
- }
- }
- }
- auto ok = [&](int x) -> int {
- int S = n + m + 1, T = n + m + 2;
- int _S = n + m + 3, _T = n + m + 4;
- Dinitz G = Dinitz(n + m + 6, _S, _T);
- for(int i = 1; i <= n; i++) {
- int one = 0, zero = 0;
- for(int j = 1; j <= m; j++) {
- one += (a[i][j] == '1');
- zero += (a[i][j] == '0');
- }
- int lo = ln[one][zero][x];
- int hi = hn[one][zero][x];
- if(lo > hi) return false;
- //edge S -> i, d = lo, c = hi
- G.addEdge(_S, i, lo);
- G.addEdge(S, _T, lo);
- G.addEdge(S, i, hi - lo);
- }
- for(int j = 1; j <= m; j++) {
- int one = 0, zero = 0;
- for(int i = 1; i <= n; i++) {
- one += (a[i][j] == '1');
- zero += (a[i][j] == '0');
- }
- int lo = lm[one][zero][x];
- int hi = hm[one][zero][x];
- if(lo > hi) return false;
- //edge j -> T, d = lo, c = hi
- G.addEdge(_S, T, lo);
- G.addEdge(j + n, _T, lo);
- G.addEdge(j + n, T, hi - lo);
- }
- for(int i = 1; i <= n; i++) {
- for(int j = 1; j <= m; j++) {
- if(a[i][j] == '*') G.addEdge(i, j + n, 1);
- }
- }
- G.addEdge(T, S, INF);
- G.Flow();
- return G.check();
- };
- int L = 0, R = max(n, m), ans = 100;
- while(L <= R) {
- int mid = (L + R) >> 1;
- if(ok(mid)) {
- ans = mid;
- R = mid - 1;
- } else L = mid + 1;
- }
- cout << ans;
- }
- int main()
- {
- ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- #ifndef ONLINE_JUDGE
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #else
- //online
- #endif
- int tc = 1, ddd = 0;
- // cin >> tc;
- while(tc--) {
- //ddd++;
- //cout << "Case #" << ddd << ": ";
- solve();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement