| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 7191 | Accepted: 2874 |
Description
On an N × N 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 that the rook moves only to the right or down. Kaka adds the number to SUM in each grid the rook visited, and replaces it with zero. It is not difficult to know the maximum SUM Kaka can obtain for his first travel. Now Kaka is wondering what is the maximum SUM he can obtain after his Kth travel. Note the SUM is accumulative during the K travels.
Input
The first line contains two integers N and K (1 ≤ N ≤ 50, 0 ≤ K ≤ 10) described above. The following N lines represents the matrix. You 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
Source
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#define N 1000000
#define M 10000
using namespace std;
int n,k,sta,end;
struct num
{
int sta,end,fan,next,cap,w;
}a[N];
int b[M],Top,pt[M],dis[M];
bool in[M];
int main()
{
//freopen("data.in","r",stdin);
void addeage(int x,int y,int cap,int w,int fan);
int EK();
while(scanf("%d %d",&n,&k)!=EOF)
{
sta = 0;
end = n*n*2+1;
Top = 0;
memset(b,-1,sizeof(b));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int w;
scanf("%d",&w);
int x = (i-1)*n+j;
int y = n*n+((i-1)*n+j);
addeage(x,y,1,w,Top+1);
addeage(y,x,0,-w,Top-1);
addeage(x,y,k-1,0,Top+1);
addeage(y,x,0,0,Top-1);
}
}
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=n-1;j++)
{
int x = (i-1)*n+j+n*n;
int y = (i-1)*n+j+1;
addeage(x,y,k,0,Top+1);
addeage(y,x,0,0,Top-1);
y = i*n+j;
addeage(x,y,k,0,Top+1);
addeage(y,x,0,0,Top-1);
}
}
for(int i=1;i<=n-1;i++)
{
int x = (i-1)*n+n+n*n;
int y = i*n+n;
addeage(x,y,k,0,Top+1);
addeage(y,x,0,0,Top-1);
}
for(int j=1;j<=n-1;j++)
{
int x = (n-1)*n+j+n*n;
int y = (n-1)*n+j+1;
addeage(x,y,k,0,Top+1);
addeage(y,x,0,0,Top-1);
}
addeage(0,1,k,0,Top+1);
addeage(1,0,0,0,Top-1);
addeage(2*n*n,end,k,0,Top+1);
addeage(end,2*n*n,0,0,Top-1);
int ans = EK();
printf("%d\n",ans);
}
return 0;
}
void addeage(int x,int y,int cap,int w,int fan)
{
a[Top].sta = x;
a[Top].end = y;
a[Top].cap = cap;
a[Top].w = w;
a[Top].fan = fan;
a[Top].next = b[x];
b[x] = Top++;
}
int spfa()
{
pt[sta] = 0;
queue<int>que;
memset(dis,-1,sizeof(dis));
memset(in,false,sizeof(in));
que.push(sta);
in[sta] = true;
dis[sta] = 0;
while(!que.empty())
{
int x= que.front();
in[x] = false;
que.pop();
for(int i = b[x];i!=-1;i=a[i].next)
{
int y = a[i].end;
int val = a[i].w;
if(a[i].cap>0&&dis[y]<(dis[x]+val))
{
dis[y] = dis[x] + val;
pt[y] = i;
if(!in[y])
{
que.push(y);
in[y] = true;
}
}
}
}
if(dis[end]==-1)
{
return 0;
}else
{
return dis[end];
}
}
int EK()
{
int res = 0;
while(true)
{
int ans = spfa();
if(ans==0)
{
break;
}
res +=ans;
int x = end;
while(x!=sta)
{
int pos = pt[x];
a[pos].cap-=1;
int fan = a[pos].fan;
a[fan].cap+=1;
x = a[pos].sta;
}
}
return res;
}
本文探讨了在矩阵中寻找经过特定次数路径后的最大累计和的优化算法,通过使用最大流和最大费用最大流的概念来解决该问题。具体地,算法首先通过构建有向图来表示矩阵中的路径和其成本,接着利用最大流或最大费用最大流的方法求解最优路径组合,最终得到在指定路径次数后的最大累计和。
426

被折叠的 条评论
为什么被折叠?



