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
| const int MAXV=1e4+10,MAXE=2e5+10,MAXN=1e2+10; const int INF=0x3f3f3f3f; int N,K,S,T; struct Net { int next,to,val,cost; }Edge[MAXE<<1]; int Head[MAXV],Cur[MAXV],Total=1; inline void addEdge(int u,int v,int w,int c) { Edge[++Total]=(Net){Head[u],v,w,c};Head[u]=Total; Edge[++Total]=(Net){Head[v],u,0,-c};Head[v]=Total; } int Dist[MAXV],ret; bool Vis[MAXV]; inline bool Spfa() { memset(Dist,0x3f,sizeof(Dist)); memcpy(Cur,Head,sizeof(Head)); std::queue<int>Q; Q.push(S),Dist[S]=0; while(!Q.empty()) { int u=Q.front();Q.pop(); Vis[u]=0; for(int e=Head[u],v;e;e=Edge[e].next) { v=Edge[e].to; if(Dist[v]>Dist[u]+Edge[e].cost&&Edge[e].val) { Dist[v]=Dist[u]+Edge[e].cost; if(!Vis[v]) Vis[v]=1,Q.push(v); } } } return Dist[T]!=INF; } int Dfs(int x,int inf) { if(x==T) return inf; int flow=0;Vis[x]=1; for(int e=Cur[x],v;e&&flow<inf;e=Edge[e].next) { v=Edge[e].to,Cur[x]=e; if(!Vis[v]&&Dist[v]==Dist[x]+Edge[e].cost&&Edge[e].val) { int k=Dfs(v,std::min(Edge[e].val,inf-flow)); if(k) { ret+=k*Edge[e].cost; Edge[e].val-=k,Edge[e^1].val+=k,flow+=k; } } } Vis[x]=0; return flow; } inline int SSP() { int r=0,flow; while(Spfa()) while(flow=Dfs(S,INF)) r+=flow; return r; } int Mp[MAXN][MAXN]; inline int getId(int x,int y,int id) { return (N*(x-1)+y)+id*N*N; } int main() { read(N,K); S=0,T=N*N*2+1; for(int i=1;i<=N;++i) for(int j=1;j<=N;++j) read(Mp[i][j]); addEdge(S,getId(1,1,0),K,0),addEdge(getId(N,N,1),T,K,0); for(int i=1;i<=N;++i) for(int j=1;j<=N;++j) addEdge(getId(i,j,0),getId(i,j,1),1,-Mp[i][j]),addEdge(getId(i,j,0),getId(i,j,1),INF,0); for(int i=1;i<=N;++i) for(int j=2;j<=N;++j) addEdge(getId(i,j-1,1),getId(i,j,0),INF,0); for(int i=2;i<=N;++i) for(int j=1;j<=N;++j) addEdge(getId(i-1,j,1),getId(i,j,0),INF,0); SSP(); write(-ret); return 0; }
|