1 #include<cstdio>
2 #include<queue>
3 #include<algorithm>
4 #include<cstring>
5
6 using namespace std;
7 const int MAXN = 2000100;
8 struct Edge{
9 int to,w,nxt;
10 Edge(){}
11 Edge(int a,int b,int c){to = a,w = b,nxt = c;}
12 }e[MAXN<<2];
13 int head[MAXN],dis[MAXN];
14 bool vis[MAXN];
15 queue<int>q;
16 int n,m,tot;
17
18 int read()
19 {
20 int x = 0,f = 1;char ch = getchar();
21 while (ch<‘0‘||ch>‘9‘) {if (ch==‘-‘)f=-1; ch = getchar();}
22 while (ch>=‘0‘&&ch<=‘9‘) x = x*10+ch-‘0‘, ch = getchar();
23 return x;
24 }
25 void add_edge(int u,int v,int w)
26 {
27 e[++tot] = Edge(v,w,head[u]);
28 head[u] = tot;
29 e[++tot] = Edge(u,w,head[v]);
30 head[v] = tot;
31 }
32 void spfa()
33 {
34 memset(dis,0x3f,sizeof(dis));
35 q.push(0);
36 vis[0] = true;
37 dis[0] = 0;
38 while (!q.empty())
39 {
40 int u = q.front();
41 q.pop();
42 for (int i=head[u]; i; i=e[i].nxt)
43 {
44 int v = e[i].to,w = e[i].w;
45 if (dis[v]>dis[u]+w)
46 {
47 dis[v] = dis[u]+w;
48 if (!vis[v])
49 {
50 q.push(v);
51 vis[v] = true;
52 }
53 }
54 }
55 vis[u] = false;
56 }
57 }
58 int main()
59 {
60 n = read(), m = read();
61 int x,y,z,tmp = (2*(n-1)*(m-1))+1;
62 for (int i=1; i<=n; ++i)
63 for (int j=1; j<m; ++j)
64 {
65 z = read();
66 x = i==1? 0:(2*(i-1)-1)*(m-1)+j;
67 y = i==n? tmp:(2*(i-1))*(m-1)+j;
68 add_edge(x,y,z);
69 }
70 for (int i=1; i<n; ++i)
71 for (int j=1; j<=m; ++j)
72 {
73 z = read();
74 x = j==1? tmp:(2*(i-1))*(m-1)+j-1;
75 y = j==m? 0:(2*(i-1))*(m-1)+j-1+m;
76 add_edge(x,y,z);
77 }
78 for (int i=1; i<n; ++i)
79 for (int j=1; j<m; ++j)
80 {
81 z = read();
82 x = (2*(i-1))*(m-1)+j;
83 y = (2*(i-1)+1)*(m-1)+j;
84 add_edge(x,y,z);
85 }
86 spfa();
87 printf("%d",dis[tmp]);
88 return 0;
89 }