描述

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. DOTween文档

    前言 DOTween现在还处于 alpha,所以还有一些缺失的功能(如路径插件,附加回调和其它的tween选项),这个文档在不久的将来可能会更新. DoTween:0.8.2.00 官方文档:http ...

  2. 关于 app测试工具

    1. 腾讯的GT 2. testin 云测 3. monkey的自动化测试 4. 纯手工的功能测试.

  3. Spring MVC之cookies跟session 数据绑定

    在我最早接触web开发的中学时代,学习的asp技术对于session的概念其实很清楚 Session("username")="张三"下次要用的时候,直接用se ...

  4. 用yo命令创建项目

    1,npm install -g yo 安装yeoman 2,npm install -g generator-webapp 安装项目脚手架(生成器) 如果安装angular的项目后面则是genera ...

  5. 判断变量是否为json对象

    var m ={a:'A'}; if(typeof m == 'object' && JSON.stringify(m).indexOf('{') == 0){//判断变量m是不是js ...

  6. 基于PXC的MySQL高可用环境简单部署

    PXC简介 Percona XtraDB Cluster(简称PXC集群)提供了MySQL高可用的一种实现方法. 1.集群是有节点组成的,推荐配置至少3个节点,但是也可以运行在2个节点上. 2.每个节 ...

  7. android 6.0(api 23) SDK,不再提供org.apache.http.*(只保留几个类)

    在使用android-async-http的时候我的apl 更新到了23,我的build version也是23的时候出现了,org.apache.http.Header这个类找不到的情况,原因是在a ...

  8. iOS开发系列--录音

    在AVFoundation框架中还要一个AVAudioRecorder类专门处理录音操作,它同样支持多种音频格式.与AVAudioPlayer类似,你完全可以将它看成是一个录音机控制类,下面是常用的属 ...

  9. Linux c实现服务端与客户端聊天

    主要利用socket通信实现,具体代码如下 客户端: #include <stdio.h> #include <stdlib.h> #include <string.h& ...

  10. 浅入ARP

    1.ARP的工作原理 IP层协议ARP的核心功能就是通过目的主机IP地址得到主机的硬件地址,然后通过硬件地址进行通信.和计算机网络中的很多技术一样,ARP协议也是使用了建立一个缓存表的思想.它规定每个 ...