#include<bits/stdc++.h>
#define N 7000005
#define M 1005
using namespace std;
struct node{
long long point,value;
};
priority_queue<node>q;
bool flag[N];
int n,m,s,num,edgenum,value,u[M],v[M];
long long dist[N];
int ver[N],edge[N],Next[N],head[N];
bool operator < (node a1,node a2){
return a1.value>a2.value;
}
void Add(int x,int y,int z){
ver[++edgenum]=y;
edge[edgenum]=z;
Next[edgenum]=head[x];
head[x]=edgenum;
}
void Dij(){
memset(dist,0x7f,sizeof(dist));
dist[s]=0;
node h;
h.point=s;h.value=0;
q.push(h);
while(q.size()){
node x=q.top();
q.pop();
if(!flag[x.point]){
flag[x.point]=true;
for(int i=head[x.point];i;i=Next[i]){
int y=ver[i];
int z=edge[i];
if(dist[x.point]+z<dist[y]){
dist[y]=dist[x.point]+z;
node g;
g.point=y;g.value=dist[y];
q.push(g);
}
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
s=0;
//横着的
num=(n-1)*(m-1)*2;
for(int j=1;j<m;j++){
scanf("%d",&value);
Add(j,num+1,value);
Add(num+1,j,value);
}
for(int i=2;i<n;i++)
for(int j=1;j<m;j++){
scanf("%d",&value);
u[i]=(i-1)*(m-1)+j;
v[i]=u[i]+m-1;
Add(u[i],v[i],value);
Add(v[i],u[i],value);
}
for(int j=1;j<m;j++){
scanf("%d",&value);
Add(num-(m-j-1),0,value);
Add(0,num-(m-j-1),value);
}
//竖着的
for(int i=1;i<n;i++){
scanf("%d",&value);
Add((m-1)*2*(i-1)+m,0,value);
Add(0,(m-1)*(i-1)*2+m,value);
for(int j=2;j<m;j++){
scanf("%d",&value);
u[i]=(m-1)*2*(i-1)+m+j-1;
v[i]=u[i]-m;
Add(u[i],v[i],value);
Add(v[i],u[i],value);
}
scanf("%d",&value);
Add((m-1)*2*(i-1)+m-1,num+1,value);
Add(num+1,(m-1)*2*(i-1)+m-1,value);
}
//斜着的
for(int i=1;i<n;i++)
for(int j=1;j<m;j++){
scanf("%d",&value);
u[i]=(m-1)*(i-1)*2+j;
v[i]=u[i]+m-1;
Add(u[i],v[i],value);
Add(v[i],u[i],value);
}
Dij();
printf("%lld\n",dist[num+1]);
return 0;
}
WA 80 找位大佬帮我看看