#include <bits/stdc++.h> using namespace std; const int maxn = 2e6+10; const int inf = 1e9; struct Node{ int v, next, w; }node[maxn*3]; int minn = inf; int N, M; int tot, head[maxn]; int dist[maxn]; bool vis[maxn]; int cnt[maxn]; int end_pos; void init(){ memset(head, -1, sizeof(head)); } void add_edge(int u, int v, int w){ node[tot].v=v,node[tot].w=w,node[tot].next=head[u],head[u]=tot++; node[tot].v=u,node[tot].w=w,node[tot].next=head[v],head[v]=tot++; } void build_graph(){ scanf("%d%d",&N,&M); end_pos=2*(N-1)*(M-1)+1; int t; if(N==1){ for(int i=1;i<M;++i){ scanf("%d",&t); if(t<minn) minn=t; } return ; } else if(M==1){ for(int i=1;i<N;++i){ scanf("%d",&t); if(t<minn) minn=t; } return ; } for(int i=1;i<=end_pos;++i) dist[i]=inf; for(int i=1;i<=2*(N-1)+1;i+=2) for(int j=1;j<M;++j){ scanf("%d",&t); if(i==1) add_edge(j,0,t); else if(i==2*(N-1)+1) add_edge(end_pos-(M-j),end_pos,t); else add_edge((i-2)*(M-1)+j,(i-1)*(M-1)+j,t); } for(int i=1;i<2*(N-1)+1;i+=2) for(int j=1;j<=M;++j){ scanf("%d",&t); if(j==1) add_edge(i*(M-1)+1,end_pos,t); else if(j==M) add_edge(i*(M-1),0,t); else add_edge(i*(M-1)+j,(i-1)*(M-1)+j-1,t); } for(int i=1;i<2*(N-1)+1;i+=2) for(int j=1;j<M;++j){ scanf("%d",&t); add_edge((i-1)*(M-1)+j,i*(M-1)+j,t); } } bool spfa(int s){ memset(cnt, 0, sizeof(cnt)), memset(vis, 0, sizeof(vis)); dist[s] = 0; cnt[s] = 0, vis[s] = true; queue<int> q; while(!q.empty()) q.pop(); q.push(s); while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = false; for(int i=head[u]; ~i; i=node[i].next){ int v=node[i].v; if(dist[v]>dist[u]+node[i].w){ dist[v] = dist[u]+node[i].w; if(!vis[v]){ cnt[v]++; vis[v] = true; q.push(v); if(cnt[v]>2*(N-1)*(M-1)+2) return false; } } } } return true; } int main(){ init(); build_graph(); if(minn == inf){ spfa(0); printf("%d\n", dist[end_pos]); } else printf("%d", minn); return 0; }
|