水题
——代码
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 51
#define M 100001
#define INF 1e9
#define min(x, y) ((x) < (y) ? (x) : (y)) int n, k, s, t, cnt, tot, sum;
int head[M], to[M], val[M], cost[M], next[M], dis[M], pre[M], a[N][N], b[N][N];
bool vis[M]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline void add2(int x, int y, int z, int c)
{
to[cnt] = y;
val[cnt] = z;
cost[cnt] = c;
next[cnt] = head[x];
head[x] = cnt++;
} inline void add(int x, int y, int z, int c)
{
add2(x, y, z, c);
add2(y, x, , -c);
} inline bool spfa()
{
int i, u, v;
std::queue <int> q;
memset(vis, , sizeof(vis));
memset(pre, -, sizeof(pre));
memset(dis, / , sizeof(dis));
q.push(s);
dis[s] = ;
while(!q.empty())
{
u = q.front(), q.pop();
vis[u] = ;
for(i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] > dis[u] + cost[i])
{
dis[v] = dis[u] + cost[i];
pre[v] = i;
if(!vis[v])
{
q.push(v);
vis[v] = ;
}
}
}
}
return pre[t] ^ -;
} int main()
{
int i, j, x, d;
n = read();
k = read();
s = , t = (n * n << ) + ;
memset(head, -, sizeof(head));
for(i = ; i <= n; i++)
for(j = ; j <= n; j++)
{
x = read(), b[i][j] = ++tot;
add(b[i][j], b[i][j] + n * n, , -x);
add(b[i][j], b[i][j] + n * n, INF, );
}
for(i = ; i <= n; i++)
for(j = ; j <= n; j++)
{
if(i < n) add(b[i][j] + n * n, b[i + ][j], INF, );
if(j < n) add(b[i][j] + n * n, b[i][j + ], INF, );
}
add(s, , k, );
add(n * n << , t, k, );
while(spfa())
{
d = INF;
for(i = pre[t]; i ^ -; i = pre[to[i ^ ]]) d = min(d, val[i]);
for(i = pre[t]; i ^ -; i = pre[to[i ^ ]])
{
val[i] -= d;
val[i ^ ] += d;
}
sum += dis[t] * d;
}
printf("%d\n", -sum);
return ;
}