# bzoj 1001 狼抓兔子

### Description

1:(x,y)<==>(x+1,y)
2:(x,y)<==>(x,y+1)
3:(x,y)<==>(x+1,y+1)

3 4

5 6 4

4 3 1

7 5 3

5 6 7 8

8 7 6 5

5 5 5

6 6 6

14

### 题解

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> Pair;
const int N = 1010;
int n, m, a1[N][N], a2[N][N], a3[N][N];
struct edge {
int to, next, val;
}e[N * N * 8];
int st[N * N * 2], tot;
void add_edge(int x, int y, int z) {
e[++tot].next = st[x];
e[tot].to = y, e[tot].val = z;
st[x] = tot;
}
int dis[N * N * 2];
bool flag[N * N * 2];
int dijsktra(int start, int end) {
memset(dis, 127, sizeof dis);
memset(flag, 0, sizeof flag);
dis[start] = 0;
priority_queue< Pair, vector<Pair>, greater<Pair> >que;
que.push(make_pair(dis[start], start));
while (!que.empty()) {
Pair now = que.top();
que.pop();
if (flag[now.second]) continue;
flag[now.second] = 1;
for (int i = st[now.second]; i; i = e[i].next)
if (dis[now.second] + e[i].val < dis[e[i].to]) {
dis[e[i].to] = dis[now.second] + e[i].val;
if (!flag[e[i].to]) que.push(make_pair(dis[e[i].to], e[i].to));
}
}
return dis[end];
}
void add(int x, int y, int z) {
//  printf("%d %d %d\n", x, y, z);
}
main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
for (int j = 1; j < m; ++j)
scanf("%d", &a1[i][j]);
for (int i = 1; i < n; ++i)
for (int j = 1; j <= m; ++j)
scanf("%d", &a2[i][j]);
for (int i = 1; i < n; ++i)
for (int j = 1; j < m; ++j)
scanf("%d", &a3[i][j]);
m--, n--;
int S = n * m * 2 + 1, T = S + 1;
for (int i = 1; i <= m; ++i)
for (int i = 1; i <= m; ++i)
add(m * (2 * n - 1) + i, T, a1[n + 1][i]);
for (int i = 1; i <= n; ++i)
add(m * (2 * (i - 1) + 1), S, a2[i][m + 1]);
for (int i = 1; i <= n; ++i)
add(m * (2 * (i - 1) + 1) + 1, T, a2[i][1]);
//  puts("");
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
add(m * (2 * (i - 1)) + j, m * (2 * (i - 1) + 1) + j, a3[i][j]);
//  puts("");
for (int i = 1; i <= n; ++i)
for (int j = 1; j < m; ++j)
add(m * (2 * (i - 1)) + j, m * (2 * (i - 1) + 1) + j + 1, a2[i][j + 1]);
//  puts("");
for (int i = 1; i < n; ++i)
for (int j = 1; j <= m; ++j)
add(m * (2 * (i - 1) + 1) + j, m * 2 * i + j, a1[i + 1][j]);
printf("%d\n", dijsktra(S, T));
}