1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
| #include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
const int MAXN = 300000,MAXM = 2400000;
const int N = 510;
struct Edge{
int from,to;
ll len;int nex;
}edge[MAXM];
int n,m,s,t;
int fir[MAXN],ecnt = 2;
int a[N][N],b[N][N],c[N][N],d[N][N];
void addedge(int a,int b,int c){s
edge[ecnt] = (Edge){a,b,c,fir[a]};
fir[a] = ecnt++;
}
struct Point{
int x;ll d;
bool operator <(const Point &a)const{
return d > a.d;
}
};
ll dis[MAXN];
bool vis[MAXN];
priority_queue<Point> q;
void dij(){
for(int i = 1;i<=n*n+2;i++) dis[i] = 2147483647;
dis[s] = 0;
q.push((Point){s,0});
while(!q.empty()){
Point now = q.top();q.pop();
int nown = now.x,nowd = dis[nown];
if(vis[nown]) continue;
vis[nown] = 1;
for(int nowe = fir[nown];nowe;nowe = edge[nowe].nex){
int v = edge[nowe].to,l = edge[nowe].len;
if(dis[v] > nowd + l){
dis[v] = nowd + l;
q.push((Point){v,dis[v]});
}
}
}
}
int _hash(int i,int j){
if(i <= 0 || j > n) return s;
if(j <= 0 || i > n) return t;
return (i-1)*n+j;
}
void init(){
scanf("%d",&n);n++;
for(int i = 1;i<=n;i++)
for(int j = 1;j<=n-1;j++)
scanf("%d",&a[i][j]);
for(int i = 1;i<=n-1;i++)
for(int j = 1;j<=n;j++)
scanf("%d",&b[i][j]);
for(int i = 1;i<=n;i++)
for(int j = 2;j<=n;j++)
scanf("%d",&c[i][j]);
for(int i = 2;i<=n;i++)
for(int j = 1;j<=n;j++)
scanf("%d",&d[i][j]);
n--;
}
void solve(){
s = n*n+1,t = n*n+2;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
addedge(_hash(i,j),_hash(i+1,j),a[i+1][j]);
addedge(_hash(i,j),_hash(i,j+1),d[i+1][j+1]);
addedge(_hash(i,j),_hash(i-1,j),c[i][j+1]);
addedge(_hash(i,j),_hash(i,j-1),b[i][j]);
}
}
for(int i = 1;i<=n;i++){
addedge(s,_hash(1,i),a[1][i]);
addedge(s,_hash(i,n),b[i][n+1]);
//addedge(,s,),addedge(,s,);
}
for(int i = 1;i<=n;i++){
addedge(_hash(i,1),t,b[i][1]);
addedge(_hash(n,i),t,a[n+1][i]);
//addedge(t,,),addedge(t,,);
}
dij();
printf("%lld\n",dis[t]);
}
signed main(){
init();
solve();
return 0;
}
|