Advertisement
BaoJIaoPisu

Untitled

Apr 11th, 2022
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.88 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. using ll = long long;
  6. using ld = long double;
  7. using ull = unsigned long long;
  8.  
  9. using pii = pair<int, int>;
  10. using pll = pair<ll, ll>;
  11. using pld = pair<ld, ld>;
  12.  
  13. #define fi first
  14. #define se second
  15. #define pb push_back
  16. #define pf push_front
  17. #define mp make_pair
  18. #define ins insert
  19. #define btpc __builtin_popcount
  20. #define btclz __builtin_clz
  21.  
  22. #define sz(x) (int)(x.size());
  23. #define all(x) x.begin(), x.end()
  24. #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
  25.  
  26. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  27.  
  28. int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
  29. int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
  30. int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
  31.  
  32. template<class X, class Y>
  33.     bool minimize(X &x, const Y &y) {
  34.         if (x > y)
  35.         {
  36.             x = y;
  37.             return true;
  38.         }
  39.         return false;
  40.     }
  41. template<class X, class Y>
  42.     bool maximize(X &x, const Y &y) {
  43.         if (x < y)
  44.         {
  45.             x = y;
  46.             return true;
  47.         }
  48.         return false;
  49.     }
  50.  
  51. const int MOD = 1e9 + 7; //998244353
  52.  
  53. template<class X, class Y>
  54.     void add(X &x, const Y &y) {
  55.         x = (x + y);
  56.         if(x >= MOD) x -= MOD;
  57.     }
  58.  
  59. template<class X, class Y>
  60.     void sub(X &x, const Y &y) {
  61.         x = (x - y);
  62.         if(x < 0) x += MOD;
  63.     }
  64.  
  65. /* Author : Le Ngoc Bao Anh, 11A5, LQD High School for Gifted Student*/
  66.  
  67. const ll INF = 1e9;
  68. const int N = 100 + 10;
  69.  
  70. struct Dinitz {
  71.     struct Edges {
  72.         int u, v;
  73.         ll cap;
  74.  
  75.         Edges() : u(), v(), cap() {}
  76.         Edges(int _u, int _v, ll _cap) : u(_u), v(_v), cap(_cap) {}
  77.     };
  78.  
  79.     vector<vector<int>> g;
  80.     vector<Edges> ed;
  81.     vector<int> dist;
  82.     vector<int> id;
  83.     int S, T;
  84.     int n;
  85.  
  86.     Dinitz() : ed(), n(), S(), T() {}
  87.     Dinitz(int _n, int _S, int _T) {
  88.         n = _n; S = _S; T = _T;
  89.         g.resize(n);
  90.         dist.resize(n);
  91.         id.resize(n);
  92.         for(int i = 0; i < n; i++) g[i].clear();
  93.         ed = vector<Edges>();
  94.     }
  95.  
  96.     void addEdge(int u, int v, ll cap) {
  97.         g[u].pb((int)ed.size());
  98.         ed.pb(Edges(u, v, cap));
  99.         g[v].pb((int)ed.size());
  100.         ed.pb(Edges(v, u, 0));
  101.     }
  102.  
  103.     bool bfs() {
  104.         for(int i = 0; i < n; i++) dist[i] = n + 5;
  105.         queue<int> q;
  106.         q.push(S); dist[S] = 0;
  107.         while(!q.empty()) {
  108.             int u = q.front(); q.pop();
  109.             for(int i : g[u]) {
  110.                 Edges e = ed[i];
  111.                 if(!e.cap) continue;
  112.                 if(dist[e.v] <= dist[u] + 1) continue;
  113.                 dist[e.v] = dist[u] + 1;
  114.                 q.push(e.v);
  115.             }
  116.         }
  117.  
  118.         return dist[T] < n + 5;
  119.     }
  120.  
  121.     ll dfs(int u, ll flow) {
  122.         if(u == T || flow == 0) return flow;
  123.  
  124.         ll ans = 0;
  125.         for(int &i = id[u]; i < (int)g[u].size(); i++) {
  126.             Edges e = ed[g[u][i]];
  127.             if(!e.cap) continue;
  128.             if(dist[e.v] != dist[u] + 1) continue;
  129.             ll f = dfs(e.v, min(flow, e.cap));
  130.             flow -= f;
  131.             ans += f;
  132.             ed[g[u][i]].cap -= f;
  133.             ed[g[u][i] ^ 1].cap += f;
  134.             if(flow == 0) return ans;
  135.         }
  136.  
  137.         return ans;
  138.     }
  139.  
  140.     ll Flow() {
  141.         ll ans = 0;
  142.         while(bfs()) {
  143.             for(int i = 0; i < n; i++) id[i] = 0;
  144.             ans += dfs(S, INF * INF);
  145.         }
  146.  
  147.         return ans;
  148.     }
  149.  
  150.     bool check() {
  151.         for(int i = 0; i < ed.size(); i++) {
  152.             if(ed[i].u < S && ed[i].v < S) continue;
  153.             int u = ed[i].u, v = ed[i].v;
  154.             if(v == S) continue;
  155.             if(u == T) continue;
  156.             if(ed[i].cap) {
  157.                 return false;
  158.             }
  159.         }
  160.  
  161.         return true;
  162.     };
  163. };
  164.  
  165. char a[N][N];
  166. int ln[N][N][N];
  167. int hn[N][N][N];
  168. int lm[N][N][N];
  169. int hm[N][N][N];
  170.  
  171. void solve() {
  172.     int n, m;
  173.     cin >> n >> m;
  174.     for(int i = 1; i <= n; i++) {
  175.         for(int j = 1; j <= m; j++) {
  176.             cin >> a[i][j];
  177.         }
  178.     }
  179.  
  180.     int v = max(n, m);
  181.     for(int i = 0; i <= m; i++) {
  182.         for(int j = 0; j <= m; j++) {
  183.             if(i + j > m) break;
  184.             int r = m - i - j;
  185.             for(int x = 0; x <= v; x++) {
  186.                 ln[i][j][x] = INF;
  187.                 hn[i][j][x] = 0;
  188.                 for(int d = 0; d <= r; d++) {
  189.                     if(abs(i + d - (j + (r - d))) <= x) {
  190.                         minimize(ln[i][j][x], d);
  191.                         maximize(hn[i][j][x], d);
  192.                     }
  193.                 }
  194.             }
  195.         }
  196.     }
  197.  
  198.     for(int i = 0; i <= n; i++) {
  199.         for(int j = 0; j <= n; j++) {
  200.             if(i + j > n) break;
  201.             int r = n - i - j;
  202.             for(int x = 0; x <= v; x++) {
  203.                 lm[i][j][x] = INF;
  204.                 hm[i][j][x] = 0;
  205.                 for(int d = 0; d <= r; d++) {
  206.                     if(abs(i + d - (j + (r - d))) <= x) {
  207.                         minimize(lm[i][j][x], d);
  208.                         maximize(hm[i][j][x], d);
  209.                     }
  210.                 }
  211.             }
  212.         }
  213.     }
  214.  
  215.     auto ok = [&](int x) -> int {
  216.         int S = n + m + 1, T = n + m + 2;
  217.         int _S = n + m + 3, _T = n + m + 4;
  218.         Dinitz G = Dinitz(n + m + 6, _S, _T);
  219.  
  220.         for(int i = 1; i <= n; i++) {
  221.             int one = 0, zero = 0;
  222.             for(int j = 1; j <= m; j++) {
  223.                 one += (a[i][j] == '1');
  224.                 zero += (a[i][j] == '0');
  225.             }
  226.  
  227.             int lo = ln[one][zero][x];
  228.             int hi = hn[one][zero][x];
  229.  
  230.             if(lo > hi) return false;
  231.             //edge S -> i, d = lo, c = hi
  232.             G.addEdge(_S, i, lo);
  233.             G.addEdge(S, _T, lo);
  234.             G.addEdge(S, i, hi - lo);
  235.         }
  236.  
  237.         for(int j = 1; j <= m; j++) {
  238.             int one = 0, zero = 0;
  239.             for(int i = 1; i <= n; i++) {
  240.                 one += (a[i][j] == '1');
  241.                 zero += (a[i][j] == '0');
  242.             }
  243.  
  244.             int lo = lm[one][zero][x];
  245.             int hi = hm[one][zero][x];
  246.  
  247.             if(lo > hi) return false;
  248.             //edge j -> T, d = lo, c = hi
  249.             G.addEdge(_S, T, lo);
  250.             G.addEdge(j + n, _T, lo);
  251.             G.addEdge(j + n, T, hi - lo);
  252.         }
  253.  
  254.         for(int i = 1; i <= n; i++) {
  255.             for(int j = 1; j <= m; j++) {
  256.                 if(a[i][j] == '*') G.addEdge(i, j + n, 1);
  257.             }
  258.         }
  259.  
  260.  
  261.         G.addEdge(T, S, INF);
  262.         G.Flow();
  263.  
  264.         return G.check();
  265.     };
  266.     int L = 0, R = max(n, m), ans = 100;
  267.     while(L <= R) {
  268.         int mid = (L + R) >> 1;
  269.         if(ok(mid)) {
  270.             ans = mid;
  271.             R = mid - 1;
  272.         } else L = mid + 1;
  273.     }
  274.  
  275.     cout << ans;
  276. }  
  277.  
  278. int main()
  279. {
  280.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  281.     #ifndef ONLINE_JUDGE
  282.     freopen("input.txt", "r", stdin);
  283.     freopen("output.txt", "w", stdout);
  284.     #else
  285.     //online
  286.     #endif
  287.  
  288.     int tc = 1, ddd = 0;
  289.     // cin >> tc;
  290.     while(tc--) {
  291.         //ddd++;
  292.         //cout << "Case #" << ddd << ": ";
  293.         solve();
  294.     }
  295. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement