1 /**************************************************************
2 Problem: 1001
3 User: Doggu
4 Language: C++
5 Result: Accepted
6 Time:2032 ms
7 Memory:122924 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <algorithm>
12 #include <cstring>
13 #include <queue>
14 #define pos(x,y) ((x-1)*m+y)
15
16 const int M = 7000000 + 10;
17 const int N = 1000000 + 10;
18 struct Edge {int v, upre, cap, flow;}g[M];
19 int head[N], ne = 0;
20 inline void adde(int u,int v,int cap) {
21 //printf("ADDE:%d %d %d\n",u,v,cap);
22 g[ne]=(Edge){v,head[u],cap,0};head[u]=ne++;
23 g[ne]=(Edge){u,head[v],cap,0};head[v]=ne++;
24 }
25
26 int n, m, u, v, cap, s, t;
27 struct DINIC {
28 int d[N];
29 bool vis[N];
30 std::queue<int> q;
31 bool BFS() {//建立层次图
32 memset(vis, 0, sizeof(vis));
33 while(!q.empty()) q.pop();
34 vis[s] = 1;d[s] = 0;q.push(s);
35 while(!q.empty()) {
36 int u = q.front();q.pop();
37 for( int i = head[u]; i != -1; i = g[i].upre ) {
38 int v = g[i].v;
39 if(!vis[v] && g[i].cap>g[i].flow) vis[v] = 1, d[v] = d[u] + 1, q.push(v);
40 }
41 }
42 return vis[t];
43 }
44
45 int cur[N];
46 int DFS(int u,int a) {//找增广路
47 if(u == t||a == 0) return a;//注意是return a
48 int f, flow = 0;
49 for( int& i = cur[u]; i != -1; i = g[i].upre ) {//不要忘了加cur
50 int v = g[i].v;
51 if(d[u] + 1 == d[v] && (f=DFS(v,std::min(a,g[i].cap-g[i].flow)))>0) {
52 g[i].flow+=f;g[i^1].flow-=f;flow+=f;a-=f;//加加减减
53 if(a==0) break;
54 }
55 }
56 return flow;
57 }
58 void maxflow() {
59 int flow = 0;
60 while(BFS()) {
61 memcpy(cur,head,sizeof(head));//每一次清零
62 flow += DFS(s,0x3f3f3f3f);
63 }
64 printf("%d\n",flow);
65 }
66 }dinic;
67 int main() {
68 memset(head,-1,sizeof(head));
69 scanf("%d%d",&n,&m);
70 for( int x = 1; x <= n; x++ ) for( int y = 1; y < m; y++ ) {
71 scanf("%d",&cap);
72 adde(pos(x,y),pos(x,y+1),cap);
73 //adde(pos(x,y+1),pos(x,y),cap);
74 }
75 for( int x = 1; x < n; x++ ) for( int y = 1; y <= m; y++ ) {
76 scanf("%d",&cap);
77 adde(pos(x,y),pos(x+1,y),cap);
78 //adde(pos(x+1,y),pos(x,y),cap);
79 }
80 for( int x = 1; x < n; x++ ) for( int y = 1; y < m; y++ ) {
81 scanf("%d",&cap);
82 adde(pos(x,y),pos(x+1,y+1),cap);
83 //adde(pos(x+1,y+1),pos(x,y),cap);
84 }
85 s=pos(1,1);t=pos(n,m);
86 dinic.maxflow();
87 return 0;
88 }
89