三月第一题。
最小割等于对偶图的最短路。
直接上就行啦。
/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <queue>
#include <utility>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
const int maxd = 1005, maxn = 2000005, maxm = 3000005, inf = 0x3f3f3f3f;
int n, m, head[maxn], cnt, dis[maxn];
priority_queue<pii, vector<pii>, greater<pii> > q;
struct _edge {
int v, w, next;
} g[maxm << 1];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline void add(int u, int v, int w) {
g[cnt] = (_edge) {v, w, head[u]};
head[u] = cnt++;
}
inline void link(int u, int v, int w) {
add(u, v, w); add(v, u, w);
}
void dijkstra(int s, int t) {
for(int i = s; i <= t; i++) dis[i] = inf;
dis[s] = 0;
q.push(pii(0, s));
while(!q.empty()) {
pii x = q.top(); q.pop();
int u = x.second;
if(dis[u] < x.first) continue;
for(int i = head[u]; ~i; i = g[i].next) if(dis[g[i].v] > dis[u] + g[i].w) {
dis[g[i].v] = dis[u] + g[i].w;
q.push(pii(dis[g[i].v], g[i].v));
}
}
}
int main() {
n = iread(); m = iread(); int s = 0, t = 2 * (m - 1) * (n - 1) + 1;
for(int i = s; i <= t; i++) head[i] = -1; cnt = 0;
for(int i = 1; i <= n; i++) for(int j = 1; j < m; j++) {
int c = iread();
if(i == 1) link(2 * (j - 1) + 2, t, c);
else if(i == n) link(s, 2 * (m - 1) * (n - 2) + 2 * (j - 1) + 1, c);
else link(2 * (m - 1) * (i - 2) + 2 * (j - 1) + 1, 2 * (m - 1) * (i - 1) + 2 * (j - 1) + 2, c);
}
for(int i = 1; i < n; i++) for(int j = 1; j <= m; j++) {
int c = iread();
if(j == 1) link(s, 2 * (m - 1) * (i - 1) + 1, c);
else if(j == m) link(2 * (m - 1) * i, t, c);
else link(2 * (m - 1) * (i - 1) + 2 * (j - 2) + 2, 2 * (m - 1) * (i - 1) + 2 * (j - 1) + 1, c);
}
for(int i = 1; i < n; i++) for(int j = 1; j < m; j++) {
int c = iread();
link(2 * (m - 1) * (i - 1) + 2 * (j - 1) + 1, 2 * (m - 1) * (i - 1) + 2 * (j - 1) + 2, c);
}
dijkstra(s, t);
printf("%d\n", dis[t]);
return 0;
}