1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4 struct node
5 {
6 int v, w;
7 }edge[6000005];
8 int fst[2000005], nxt[6000005], sss, ttt, dis[2000005], q[2000005], front, back;
9 bool inq[2000005];
10
11 void qscanf(int &x)
12 {
13 char c = getchar();
14 x = 0;
15 while(c < ‘0‘ || c > ‘9‘)
16 c = getchar();
17 while(c >= ‘0‘ && c <= ‘9‘)
18 x = x * 10 + c - ‘0‘, c = getchar();
19 }
20
21 void addedge(int i, int u, int v, int w)
22 {
23 edge[i << 1] = (node){v, w}, nxt[i << 1] = fst[u], fst[u] = i << 1;
24 edge[i << 1 | 1] = (node){u, w}, nxt[i << 1 | 1] = fst[v], fst[v] = i << 1 | 1;
25 }
26
27 void SPFA()
28 {
29 memset(dis, 63, sizeof(dis));
30 dis[sss] = 0, inq[sss] = q[++back] = sss;
31 while(front != back)
32 {
33 int u = q[++front % 2000000];
34 inq[u] = false, front %= 2000000;
35 for(int i = fst[u]; i; i = nxt[i])
36 {
37 int v = edge[i].v, w = edge[i].w;
38 if(dis[v] > dis[u] + w)
39 {
40 dis[v] = dis[u] + w;
41 if(!inq[v])
42 {
43 dis[v] = dis[u] + w;
44 inq[v] = true;
45 q[++back % 2000000] = v;
46 back %= 2000000;
47 }
48 }
49 }
50 }
51 }
52
53 int main()
54 {
55 int n, m, etot = 0;
56 qscanf(n), qscanf(m);
57 n--, m--;
58 if(n && m)
59 {
60 sss = n * m * 2 + 1, ttt = n * m * 2 + 2;
61 for(int i = 1; i <= n + 1; i++)
62 for(int j = 1; j <= m; j++)
63 {
64 int u = ((i - 2) * m + j) * 2 - 1, v = ((i - 1) * m + j) * 2, w;
65 qscanf(w);
66 if(i == 1)
67 addedge(++etot, sss, v, w);
68 else if(i == n + 1)
69 addedge(++etot, u, ttt, w);
70 else
71 addedge(++etot, u, v, w);
72 }
73 for(int i = 1; i <= n; i++)
74 for(int j = 1; j <= m + 1; j++)
75 {
76 int u = ((i - 1) * m + j) * 2 - 2, v = ((i - 1) * m + j) * 2 - 1, w;
77 qscanf(w);
78 if(j == 1)
79 addedge(++etot, ttt, v, w);
80 else if(j == m + 1)
81 addedge(++etot, u, sss, w);
82 else
83 addedge(++etot, u, v, w);
84 }
85 for(int i = 1; i <= n; i++)
86 for(int j = 1; j <= m; j++)
87 {
88 int u = ((i - 1) * m + j) * 2 - 1, v = ((i - 1) * m + j) * 2, w;
89 qscanf(w), addedge(++etot, u, v, w);
90 }
91 SPFA();
92 }
93 else
94 {
95 if(m)
96 n = m;
97 dis[ttt] = 2147483647;
98 for(int i = 1; i <= n; i++)
99 {
100 qscanf(fst[i]);
101 if(dis[ttt] > fst[i])
102 dis[ttt] = fst[i];
103 }
104 }
105 printf("%d\n", dis[ttt]);
106 return 0;
107 }