#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 105
#define INF 2147483647
int n, m;
int a[maxn], b[maxn];
int c[maxn][maxn];
void input() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", a + i);
}
for (int i = 1; i <= m; i++) {
scanf("%d", b + i);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", c[i] + j);
}
}
}
struct Edge {
int v, flow, cost, next;
};
struct Graph {
Edge edge[(maxn * maxn + 2 * maxn) * 2];
int head[maxn * 2];
int cnt;
void __add_edge(int u, int v, int flow, int cost) {
cnt++;
edge[cnt].v = v;
edge[cnt].flow = flow;
edge[cnt].cost = cost;
edge[cnt].next = head[u];
head[u] = cnt;
}
void add_edge(int u, int v, int flow, int cost) {
__add_edge(u, v, flow, cost);
__add_edge(v, u, 0, -cost);
}
int s, t;
int min(int a, int b) {
return a < b ? a : b;
}
int max_flow = 0, min_cost = 0;
// 经过的总流量
int flow_[maxn];
// 经过的总价格
int cost_[maxn];
// 记录路径
int pre[maxn];
int last[maxn];
bool inq[maxn];
bool spfa() {
memset(cost_, 0x3f, sizeof(cost_));
cost_[s] = 0;
queue < int > q;
q.push(s);
memset(inq, false, sizeof(inq));
inq[s] = true;
memset(flow_, 0, sizeof(flow_));
flow_[s] = INF;
while (!q.empty()) {
int u = q.front(); q.pop();
inq[u] = false;
for (int i = head[u]; i; i = edge[i].next) {
int v = edge[i].v, f = edge[i].flow, c = edge[i].cost;
if (f > 0 && cost_[v] > cost_[u] + c) {
cost_[v] = cost_[u] + c;
flow_[v] = min(flow_[u], f);
pre[v] = u;
last[v] = i;
if (!inq[v]) {
q.push(v);
inq[v] = true;
}
}
}
}
return cost_[t] != 0x3f3f3f3f;
}
void mcmf() {
while (spfa()) {
max_flow += flow_[t];
min_cost += flow_[t] * cost_[t];
int now = t;
while (now != s) {
edge[last[now]].flow -= flow_[t];
edge[last[now] ^ 1].flow += flow_[t];
now = pre[now];
}
}
}
void init(bool smax) {
int x = smax ? -1 : 1;
cnt = 1;
s = 0;
t = n + m + 1;
for (int i = 1; i <= n; i++) {
add_edge(s, i, a[i], x * 0);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
add_edge(i, j + n, INF, x * c[i][j]);
}
}
for (int i = 1; i <= m; i++) {
add_edge(i + n, t, b[i], x * 0);
}
}
} g1, g2;
signed main() {
input();
g1.init(false);
g1.mcmf();
g2.init(true);
g2.mcmf();
printf("%d\n%d", g1.min_cost, -g2.min_cost);
return 0;
}
要加优化吗?