描述

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 theK travels.

输入

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.

输出

The maximum SUM Kaka can obtain after his Kth travel.

样例输入

3 2
1 2 3
0 2 1
1 4 2

样例输出

15

来源

POJ Monthly--2007.10.06, Huang, Jinsong

正解:网络流(最小费用最大流)

解题报告:

2016年北京大学信息学奥赛训练营上机考核第三场 B题

  大致题意是给定一个网格图,从左上角走到右下角,并且拿走经过的格子里面的数,只能往右或者往下走。总共走k次,问总和最大是多少。

  因为以前做过一道NOIP的类似题目,所以一见到这道题就马上想DP,结果发现不对。NOIP那道题是双线程DP,空间和时间都是允许的,而这道题是k次,要开2*k维,显然会炸。

  机智的我马上想起以前在codevs上面看过这道题,似乎是一模一样的。并且记得是网络流。然而最后没打出来,并不会建模,还是网络流题目做太少了。

  这道题其实很简单,模型也很容易想到。可以看出本题就是求最大费用最大流,我们把图里的数字改成负数就可以变成最小费用最大流,最后取相反数就可以了。

  我参考了这份博客,讲的还比较清楚:http://blog.csdn.net/qq172108805/article/details/7857503

  

  如上图所示,我们把一个点拆成两个点,并且用两条边相连,一条权值为这个点的权值,流量为1;另一条权值为0,流量为k-1(反向边都要分别添加)

  再加上点之间的相连,容易想到这样建模可以达到题目要求的目的

  代码如下:

 //It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXN = ;
const int MAXD = ;
const int MAXM = ;
const int inf = ;
int n,k;
int a[MAXN][MAXN];
int first[MAXD],dis[MAXD];
bool pd[MAXD];
int pre[MAXD];
int ecnt=;
int s,t;
int ans;
queue<int>Q; struct edge{
int to,f,next,u;
int w;
}e[MAXM]; inline int getint()
{
int w=,q=;
char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar();
if (c=='-') q=, c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar();
return q ? -w : w;
} inline void link(int x,int y,int w,int z){
e[++ecnt].next=first[x]; first[x]=ecnt; e[ecnt].to=y; e[ecnt].f=z; e[ecnt].w=w; e[ecnt].u=x;
e[++ecnt].next=first[y]; first[y]=ecnt; e[ecnt].to=x; e[ecnt].f=; e[ecnt].w=-w; e[ecnt].u=y;
} inline int spfa(){//EK
//根据边权跑最短路
while(!Q.empty()) Q.pop();
memset(pd,,sizeof(pd));
//memset(pre,0,sizeof(pre));
//memset(flow,0,sizeof(flow));
for(int i=;i<=t;i++) dis[i]=inf,pre[i]=-;
pd[s]=; Q.push(s); dis[s]=;
while(!Q.empty()){
int u=Q.front(); Q.pop(); pd[u]=;
//if(u==t) break;
for(int i=first[u];i;i=e[i].next) {
if(e[i].f>) {
int v=e[i].to;
if(dis[v]>dis[u]+e[i].w) {//限制流
dis[v]=dis[u]+e[i].w;
pre[v]=i;
if(!pd[v]) { Q.push(v); pd[v]=; }
}
}
}
}
if(dis[t]==inf) return -;
return ;
} inline int update(){
int total=; int f=inf;
for(int i=pre[t];e[i].u!=s;i=pre[e[i].u]) f=min(f,e[i].f); for(int i=pre[t];e[i].u!=s;i=pre[e[i].u]){
total+=e[i].w*f;
e[i].f-=f;
e[i^].f+=f;
} return total;
} inline void solve(){
while(scanf("%d%d",&n,&k)!=EOF) {
for(int i=;i<=n;i++) for(int j=;j<=n;j++) a[i][j]=getint();
ecnt=;
memset(first,,sizeof(first));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++) {
int now=(i-)*n+j-;
link(now*,now*+,-a[i][j],); link(now*,now*+,,k-);//拆成两个点,并且连边
} for(int i=;i<=n;i++) //向右连边
for(int j=;j<n;j++) {//最后一列无需连边
int now=(i-)*n+j-;
link(now*+,now*+,,k);
} for(int i=;i<n;i++) //向下连边
for(int j=;j<=n;j++) {//最后一行无需连边
int now=(i-)*n+j-;
link(now*+,(now+n)*,,k);
} s=n*n*; t=s+;
link(s,,,k); link(s-,t,,k); ans=;
while() {
int daan=spfa();
if(daan==-) break;
ans+=update();
}
printf("%d\n",-ans);
} } int main()
{
solve();
return ;
}

POJ3422 Kaka's Matrix Travels的更多相关文章

  1. poj3422 Kaka's Matrix Travels(最小费用最大流问题)

    /* poj3422 Kaka's Matrix Travels 不知道 k次 dp做为什么不对??? 看了大牛的代码,才知道还可以这样做! 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序 ...

  2. POJ3422 Kaka's Matrix Travels 【费用流】*

    POJ3422 Kaka's Matrix Travels Description On an N × N chessboard with a non-negative number in each ...

  3. POJ3422 Kaka's Matrix Travels[费用流]

    Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9522   Accepted:  ...

  4. POJ 3422 Kaka's Matrix Travels

    Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9567   Accepted:  ...

  5. POJ 3422 Kaka's Matrix Travels(费用流)

    Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6792   Accepted:  ...

  6. 【poj3422】 Kaka's Matrix Travels

    http://poj.org/problem?id=3422 (题目链接) 题意 N*N的方格,每个格子中有一个数,寻找从(1,1)走到(N,N)的K条路径,使得取到的数的和最大. Solution ...

  7. POJ3422或洛谷2045 Kaka's Matrix Travels

    POJ原题链接 洛谷原题链接 很裸的费用流. 将每个点\(x\)拆成\(x_1,x_2\),并从\(x_1\)向\(x_2\)连一条容量为\(1\),费用为该点的权值的边,以及一条容量为\(+\inf ...

  8. POJ3422:Kaka's Matrix Travels——题解

    http://poj.org/problem?id=3422 题目大意: 从左上角走到右下角,中途取数(数>=0),然后该点的数变为0,求走k的总价值和最大值. ———————————————— ...

  9. POJ 3422 Kaka's Matrix Travels 【最小费用最大流】

    题意: 卡卡有一个矩阵,从左上角走到右下角,卡卡每次只能向右或者向下.矩阵里边都是不超过1000的正整数,卡卡走过的元素会变成0,问卡卡可以走k次,问卡卡最多能积累多少和. 思路: 最小费用最大流的题 ...

随机推荐

  1. flex+AS3编程规范

    flex+AS3编程规范 Flex+AS3编码规范 http://www.cnblogs.com/jiahuafu/   1.  缩写: 尽量避免使用缩写,使用缩写时尽量和Flex保持一致.但要记住一 ...

  2. Eclipse快捷键列表大全

    from: http://hi.baidu.com/lzycsd/item/c6febccceacc173c44941684 from: http://www.open-open.com/bbs/vi ...

  3. android源码在线查看

    http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/

  4. C和指针 3.9作用域、存储类型示例

    ; extern int b; static int c; int d( int e ) { ; register int b; ; extern int a; ... { int e; int a; ...

  5. addEvent和removeEvent优化写法

    ;(function(){ /** * 初始化分支是一种优化模式,当知道某个条件在整个生命周期内都不会发生变化时,仅对该条件测试一次. */ // 一般写法 var util = { addEvent ...

  6. 快捷键forMac

    1.手动补全快捷键 设置completion+basic或者completion+smartType 2.快速导入指定API的包 command+1

  7. DWZ集成的xhEditor编辑器浏览本地图片上传的设置

    有关xhEditor的文件上传配置官方文档链接:http://i.hdu.edu.cn/dcp/dcp/comm/xheditor/demos/demo08.html 一.xhEditor图片上传的配 ...

  8. C#中的bitmap类和图像像素值获取方法

    一.Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的主要方法和属性如下: 1. GetP ...

  9. [CareerCup] 7.6 The Line Passes the Most Number of Points 经过最多点的直线

    7.6 Given a two-dimensional graph with points on it, find a line which passes the most number of poi ...

  10. LeetCode:Gray Code(格雷码)

    题目链接 The gray code is a binary numeral system where two successive values differ in only one bit. Gi ...