1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #include <bits/stdc++.h> #define MAX_N 500000 #define MAX_M 500000 #define INF 0x3f3f3f3f #define mid ((p+q)>>1) using namespace std; template <class T> inline void read(T &x) { x = 0; int c = getchar(), f = 1; for (; !isdigit(c); c = getchar()) if (c == 45) f = -1; for (; isdigit(c); c = getchar()) (x *= 10) += f*(c-'0'); } int r, c, x[205], y[205], P, Q; int n, s, t, ss, tt, cnt, d[MAX_N+5], pr[MAX_N+5], cr[MAX_N+5]; struct node {int v, c, nxt;} E[MAX_M+5]; void init() {cnt = 0, s = 0, t = r+c+1, ss = t+1, tt = t+2, memset(pr, -1, sizeof pr), memset(d, 0, sizeof d);} void insert(int u, int v, int c) {E[cnt] = (node){v, c, pr[u]}, pr[u] = cnt++;} void addedge(int u, int v, int c) {insert(u, v, c), insert(v, u, 0);} bool BFS() { queue <int> que; que.push(s); memset(d, -1, sizeof d), d[s] = 0; while (!que.empty()) { int u = que.front(); que.pop(); for (int i = pr[u]; ~i; i = E[i].nxt) { int v = E[i].v, c = E[i].c; if (~d[v] || !c) continue; d[v] = d[u]+1, que.push(v); } } return ~d[t]; } int DFS(int u, int flow) { if (u == t) return flow; int ret = 0; for (int i = pr[u]; ~i; i = E[i].nxt) { int v = E[i].v, c = E[i].c; if (d[u]+1 != d[v] || !c) continue; int tmp = DFS(v, min(flow, c)); E[i].c -= tmp, E[i^1].c += tmp; flow -= tmp, ret += tmp; if (!flow) break; } if (!ret) d[u] = -1; return ret; } int Dinic() {int ret = 0; while (BFS()) ret += DFS(s, INF); return ret;} bool check(int tans) { int into = 0, outo = 0; init(), n = r+c+2, addedge(tt, ss, INF); for (int i = 1; i <= r; i++) for (int j = 1; j <= c; j++) addedge(i, j+r, Q-P), d[i] += P, d[j+r] -= P; for (int i = 1; i <= r; i++) addedge(ss, i, 2*tans), d[ss] += x[i]-tans, d[i] -= x[i]-tans; for (int i = 1; i <= c; i++) addedge(i+r, tt, 2*tans), d[i+r] += y[i]-tans, d[tt] -= y[i]-tans; for (int i = 1; i <= tt; i++) if (i^t) { if (d[i] < 0) addedge(s, i, -d[i]), into -= d[i]; if (d[i] > 0) addedge(i, t, d[i]), outo += d[i]; } return into == outo && Dinic() == into; } int bi_search(int p, int q) {int ret = -1; while (p <= q) if (check(mid)) ret = mid, q = mid-1; else p = mid+1; return ret;} int main() { read(r), read(c); for (int i = 1; i <= r; i++) for (int j = 1, val; j <= c; j++) read(val), x[i] += val, y[j] += val; return read(P), read(Q), printf("%d", bi_search(0, 200000)), 0; }
|