#include "stdio.h" //额,按最小费用最大流的模板来的!poj 3422 #include "string.h" #include "queue" using namespace std; #define N 5005 #define INF 0x3fffffff struct node{ int u,v,w,k; int next; }edge[4*N]; int n,ans,idx; bool mark[N]; int dis[N],route[N],head[N]; void init(); void EK(int start,int end); bool SPFA(int start,int end); void adde(int u,int v,int w,int k); void addedge(int u,int v,int w,int k); int main() { int esp; int i,j; int x,y,w,k; while(scanf("%d %d",&n,&esp)!=-1) { init(); k=n*n; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { scanf("%d",&w); x = (i-1)*n+j; adde(x,x+k,-w,1); adde(x,x+k,0,esp-1); if(j!=n) adde(x+k,x+1,0,esp); if(i!=n) adde(x+k,x+n,0,esp); } } int start=0,end=2*n*n+1; adde(start,1,0,esp); adde(2*k,end,0,esp); while(SPFA(start,end)) EK(start,end); printf("%d ",-ans); } return 0; } void init() { idx = 0; ans = 0; memset(head,-1,sizeof(head)); } void adde(int u,int v,int w,int k) { addedge(u,v,w,k); addedge(v,u,-w,0); } void addedge(int u,int v,int w,int k) { edge[idx].u = u; edge[idx].v = v; edge[idx].w = w; edge[idx].k = k; edge[idx].next = head[u]; head[u] = idx; idx++; } bool SPFA(int start,int end) { int i; int x,y; memset(route,-1,sizeof(route)); memset(mark,false,sizeof(mark)); for(i=0;i<N;i++) dis[i] = INF; dis[0] = 0; queue<int> q; q.push(start); mark[start] = true; while(!q.empty()) { x = q.front(); q.pop(); for(i=head[x];i!=-1;i = edge[i].next) { y = edge[i].v; if(edge[i].k && dis[y]>dis[x]+edge[i].w) { dis[y] = dis[x] + edge[i].w; route[y] = i; if(mark[y]==false) { mark[y] = true; q.push(y); } } } mark[x] = false; } if(route[end]==-1) return false; return true; } void EK(int start,int end) { int x,y; y = route[end]; while(y!=-1) { x = y^1; ans += edge[y].w; edge[y].k--; edge[x].k++; y = route[edge[y].u]; } }