1 #include <bits/stdc++.h>
2 using namespace std;
3 const int maxn = 205, inf = 0x3f3f3f3f;
4 struct Edge {
5 int from, to, cap, flow, cost;
6 };
7 struct MCMF {
8 int n, m, s, t;
9 vector<Edge> edges;
10 vector<int> G[maxn];
11 int inq[maxn];
12 int d[maxn];
13 int p[maxn];
14 int a[maxn];
15
16 void init(int n) {
17 this->n = n;
18 for (int i = 1; i <= n; ++i) G[i].clear();
19 edges.clear();
20 }
21
22 void AddEdge(int from, int to, int cap, int cost) {
23 edges.push_back((Edge){from, to, cap, 0, cost});
24 edges.push_back((Edge){to, from, 0, 0, -cost});
25 m = edges.size();
26 G[from].push_back(m-2);
27 G[to].push_back(m-1);
28 }
29 bool BellmanFord(int s, int t, int& flow, int& cost) {
30 for (int i = 1; i <= n; ++i) d[i] = inf;
31 memset(inq, 0, sizeof(inq));
32 d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = inf;
33
34 queue<int> que;
35 que.push(s);
36 while (!que.empty()) {
37 int u = que.front(); que.pop();
38 inq[u] = 0;
39 for (int i = 0; i < G[u].size(); ++i) {
40 Edge& e = edges[G[u][i]];
41 if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
42 d[e.to] = d[u] + e.cost;
43 p[e.to] = G[u][i];
44 a[e.to] = min(a[u], e.cap-e.flow);
45 if (!inq[e.to]) { que.push(e.to); inq[e.to] = 1; }
46 }
47 }
48 }
49 if (d[t] == inf) return false;
50 flow += a[t];
51 cost += d[t] * a[t];
52 int u = t;
53 while (u != s) {
54 edges[p[u]].flow += a[t];
55 edges[p[u]^1].flow -= a[t];
56 u = edges[p[u]].from;
57 }
58 return true;
59 }
60 int mincost(int s, int t) {
61 int flow = 0, cost = 0;
62 while (BellmanFord(s, t, flow, cost));
63 return cost;
64 }
65 }mcmf;
66 int a[maxn], b[maxn], c[maxn][maxn];
67 int main() {
68 int m, n; scanf("%d%d",&m,&n);
69 int s = m+n+1, t = m+n+2;
70
71 for (int i = 1; i <= m; ++i) scanf("%d",&a[i]);
72 for (int j = 1; j <= n; ++j) scanf("%d",&b[j]);
73 for (int i = 1; i <= m; ++i) {
74 for (int j = 1; j <= n; ++j) {
75 scanf("%d",&c[i][j]);
76 }
77 }
78 // 最小费用最大流
79 mcmf.init(n+m+2);
80 for (int i = 1; i <= m; ++i) {
81 mcmf.AddEdge(s,i,a[i],0);
82 }
83 for (int i = 1; i <= m; ++i) {
84 for (int j = 1; j <= n; ++j) {
85 mcmf.AddEdge(i,j+m,inf,c[i][j]);
86 }
87 }
88 for (int j = 1; j <= n; ++j) {
89 mcmf.AddEdge(j+m,t,b[j],0);
90 }
91 printf("%d\n",mcmf.mincost(s,t));
92
93 // 最大费用最大流
94 mcmf.init(n+m+2);
95 for (int i = 1; i <= m; ++i) {
96 mcmf.AddEdge(s,i,a[i],0);
97 }
98 for (int i = 1; i <= m; ++i) {
99 for (int j = 1; j <= n; ++j) {
100 mcmf.AddEdge(i,j+m,inf,-c[i][j]);
101 }
102 }
103 for (int j = 1; j <= n; ++j) {
104 mcmf.AddEdge(j+m,t,b[j],0);
105 }
106 printf("%d\n",-mcmf.mincost(s,t));
107 return 0;
108 }