Kaka ' s Matrix travels
Time Limit: 1000MS |
|
Memory Limit: 65536K |
Total submissions: 9283 |
|
accepted: 3758 |
Description
On a nxn chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the Right-bottom one, taking care, the rook moves Y to the right or down. Kaka adds the number to SUM in each grid the rook visited, and replaces it with zero. It isn't difficult to know the maximum SUM Kaka can obtain for his. Now Kaka are wondering what is the maximum SUM and can obtain after his Kth. The SUM is accumulative during the K travels.
Input
The contains two integers N and K (1≤N≤50, 0≤k≤10) described above. The following N lines represents the matrix. Can assume the numbers in the matrix are no more than 1000.
Output
The maximum SUM Kaka can obtain after his Kth travel.
Sample Input
3 2
1 2 3 0 2 1 1 4 2
Sample Output
15
Ask: There is a n*n matrix, now to go from the upper left corner to the lower right corner to go k times, each one pass once the weight of the value of 0, now the maximum weight
Train of thought: a point to be split into two points, the two points with two sides, a capacity of 1, the cost of the right, a capacity of k, the cost of 0 (even the end of the line can be connected)
This will ensure that only the first time you will go to the side of the cost of the big, feel good clever ah
Code:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <
Cmath> #include <queue> using namespace std;
#define N 5050 #define INF 999999999 struct Edge {int u,v,next,cap,cost;} Edge[n*n];
int cnt,head[n];
int ma[55][55];
int dir[2][2]= {1,0,0,1};
int vis[n],pp[n],d[n],sumflow;
void Init () {cnt=0;
Memset (head) (head,-1,sizeof);
} void Addedge (int u,int v,int cap,int cost) {edge[cnt].u=u;
Edge[cnt].v=v;
Edge[cnt].cap=cap;
Edge[cnt].cost=cost;
Edge[cnt].next=head[u];
head[u]=cnt++;
Edge[cnt].u=v;
Edge[cnt].v=u;
Edge[cnt].cap=0;
Edge[cnt].cost=-cost;
EDGE[CNT].NEXT=HEAD[V];
head[v]=cnt++;
int SPFA (int s,int t,int n) {queue<int>q;
memset (Vis) (vis,0,sizeof);
memset (pp,-1,sizeof (PP));///pp[i] represents the number for (int i=0; i<=n; i++) D[i]=-inf on the shortest path with the end of I.
d[s]=0;
Vis[s]=1;
Q.push (s); while (!q.empty ()) {int u=q.frOnt ();
Q.pop ();
vis[u]=0;
for (int i=head[u]; I!=-1 i=edge[i].next) {int v=edge[i].v;
if (edge[i].cap>0&&d[v]<d[u]+edge[i].cost) {d[v]=d[u]+edge[i].cost;
Pp[v]=i;
if (!vis[v]) {vis[v]=1;
Q.push (v);
if (D[t]==-inf) return 0;///cannot find a route to the end of the road return 1;
int MCMF (int s,int t,int n) {int mincost=0,minflow,flow=0;///max cost, minimum flow in path, total flow while (SPFA (s,t,n))///find the current longest road
{minflow=inf+1; for (int i=pp[t]; i!=-1 i=pp[edge[i].u]) minflow=min (MINFLOW,EDGE[I].CAP);///find the smallest traffic flow+=minflow from the path;
Total flow plus minimum flow for (int i=pp[t]; I!=-1 i=pp[edge[i].u]) {edge[i].cap-=minflow;///current edge minus minimum flow
edge[i^1].cap+=minflow;///reverse side plus minimum flow} mincost+=d[t]*minflow;///minimum cost equals path and * traffic per path (how many times) } Sumflow=flow;
return mincost;
int main () {int n,m;
while (~SCANF ("%d%d", &n,&m)) {init ();
for (int i=1; i<=n; i++) for (int j=1; j<=n; j + +) scanf ("%d", &ma[i][j]);
int s=0,t=n*n*2+1;
Addedge (s,1,m,0); for (int i=1; i<=n; i++) {for (int j=1; j<=n; J + +) {Addedge ((i-1) *n+
J, (I-1) *n+j+n*n,1,ma[i][j]);
Addedge ((i-1) *n+j, (i-1) *n+j+n*n,m,0);
for (int k=0; k<2; k++) {int x=i+dir[k][0],y=j+dir[k][1]; if (x<1| | x>n| | y<1| |
Y>n) continue;
Addedge ((i-1) *n+j+n*n, (x-1) *n+y,m,0);
}} Addedge (n*n*2,t,m,0);
printf ("%d\n", MCMF (s,t,t));
return 0;
}