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 64 65 66 67 68 69 70 71 72 73
| #include <bits/stdc++.h> #define MAX_N 5000 #define MAX_M 600000 #define INF 0x3f3f3f3f 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 n, m, s, t, cnt, tot, mp[55][55]; int d[MAX_N+5], pr[MAX_N+5], cr[MAX_N+5]; struct node {int v, c, nxt;} E[MAX_M+5]; int pos(int x, int y, int id) {return n*m*(id-1)+(x-1)*m+y;} void init() {s = 0, t = n*m*2+1, cnt = 0, memset(pr, -1, sizeof pr);} 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; } void cpy() {for (int i = s; i <= t; i++) cr[i] = pr[i];} void rec() {for (int i = s; i <= t; i++) pr[i] = cr[i];} int Dinic() {int ret = 0; cpy(); while (BFS()) ret += DFS(s, INF), rec(); return ret;} int main() { read(n), read(m), init(); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) read(mp[i][j]); for (int i = 1; i <= n; i++) for (int j = 1, mx = 0; j <= m; j++, tot += mx, mx = 0) if (mp[i][j] == -1) { addedge(s, pos(i, j, 1), INF); for (int k = i; k >= 1; k--) mx = max(mx, max(mp[k][j], 0)); for (int k = i; k > 1; k--) addedge(pos(k, j, 1), pos(k-1, j, 1), mx-max(mp[k][j], 0)); } else if (mp[i][j] == -2) { addedge(s, pos(i, j, 1), INF); for (int k = i; k <= n; k++) mx = max(mx, max(mp[k][j], 0)); for (int k = i; k < n; k++) addedge(pos(k, j, 1), pos(k+1, j, 1), mx-max(mp[k][j], 0)); } else if (mp[i][j] == -3) { addedge(pos(i, j, 2), t, INF); for (int k = j; k >= 1; k--) mx = max(mx, max(mp[i][k], 0)); for (int k = j; k > 1; k--) addedge(pos(i, k-1, 2), pos(i, k, 2), mx-max(mp[i][k], 0)); } else if (mp[i][j] == -4) { addedge(pos(i, j, 2), t, INF); for (int k = j; k <= m; k++) mx = max(mx, max(mp[i][k], 0)); for (int k = j; k < m; k++) addedge(pos(i, k+1, 2), pos(i, k, 2), mx-max(mp[i][k], 0)); } else addedge(pos(i, j, 1), pos(i, j, 2), INF); return printf("%d\n", tot-Dinic()), 0; }
|