1 #include <stdio.h>
2 #include <queue>
3 #include <string.h>
4
5 using namespace std;
6
7 struct edge {
8 int to,w,next;
9 }e[6000100];
10 struct node {
11 int now, dist;
12 node() { }
13 node(int _now,int _dist) {
14 now=_now;
15 dist=_dist;
16 }
17 bool operator <(const node x) const {
18 return dist > x.dist;
19 }
20 };
21
22 int n, m, num, sum, head[2000100], d[2000100];
23 bool flag[2000100];
24
25 inline void add(int _x,int _y,int _w) {
26 e[++num].to=_y;
27 e[num].w=_w;
28 e[num].next=head[_x];
29 head[_x]=num;
30 }
31
32 inline void getint(int &_x) {
33 int x=0,f=1;char ch=getchar();
34 while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘) f=-1; ch=getchar();}
35 while(ch>=‘0‘&&ch<=‘9‘) {x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
36 _x=x*f;
37 }
38
39 int main() {
40 getint(n), getint(m);
41 if (n==1 || m==1) {
42 if(n>m) swap(n,m);
43 int ans=2100000000;
44 for (int i=1,_xy;i<m;++i) {
45 getint(_xy);
46 if(_xy<ans) ans=_xy;
47 }
48 printf("%d\n",ans);
49 return 0;
50 }
51 int l=n-1,r=m-1;
52 sum=2*l*r;
53 for (int i=1,_xy;i<=n;++i) {
54 for (int j=1,_t;j<m;++j) {
55 getint(_xy);
56 _t=(i-1)*r+j;
57 int x,y;
58 y=_t<<1;
59 x=y-2*r-1;
60 if(i==1) x=0;
61 else if(i==n) y=sum+1;
62 add(x,y,_xy);
63 add(y,x,_xy);
64 }
65 }
66 for (int i=1,_xy;i<n;++i) {
67 for (int j=1,_t;j<=m;++j) {
68 getint(_xy);
69 _t=(i-1)*r+j-1;
70 int x,y;
71 x=_t<<1;
72 y=x|1;
73 if(j==1) x=sum+1;
74 else if(j==m) y=0;
75 add(x,y,_xy);
76 add(y,x,_xy);
77 }
78 }
79 for (int i=1,_xy;i<n;++i) {
80 for (int j=1,_t;j<m;++j) {
81 getint(_xy);
82 _t=(i-1)*r+j;
83 int x,y;
84 y=_t<<1;
85 x=y-1;
86 add(x,y,_xy);
87 add(y,x,_xy);
88 }
89 }
90 priority_queue<node> q;
91 for (int i=1;i<=sum+1;++i) d[i]=210000000;
92 q.push(node(0,0));
93 while(!q.empty()) {
94 int x=q.top().now;
95 q.pop();
96 if(flag[x]) continue;
97 for (int i=head[x];i;i=e[i].next) {
98 int to=e[i].to;
99 if(d[to]>d[x]+e[i].w) {
100 d[to]=e[i].w+d[x];
101 q.push(node(to,d[to]));
102 }
103 }
104 }
105 printf("%d\n",d[sum+1]);
106 return 0;
107 }