POJ3422 Kaka's Matrix Travels
描述
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的更多相关文章
- poj3422 Kaka's Matrix Travels(最小费用最大流问题)
/* poj3422 Kaka's Matrix Travels 不知道 k次 dp做为什么不对??? 看了大牛的代码,才知道还可以这样做! 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序 ...
- POJ3422 Kaka's Matrix Travels 【费用流】*
POJ3422 Kaka's Matrix Travels Description On an N × N chessboard with a non-negative number in each ...
- POJ3422 Kaka's Matrix Travels[费用流]
Kaka's Matrix Travels Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9522 Accepted: ...
- POJ 3422 Kaka's Matrix Travels
Kaka's Matrix Travels Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9567 Accepted: ...
- POJ 3422 Kaka's Matrix Travels(费用流)
Kaka's Matrix Travels Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6792 Accepted: ...
- 【poj3422】 Kaka's Matrix Travels
http://poj.org/problem?id=3422 (题目链接) 题意 N*N的方格,每个格子中有一个数,寻找从(1,1)走到(N,N)的K条路径,使得取到的数的和最大. Solution ...
- POJ3422或洛谷2045 Kaka's Matrix Travels
POJ原题链接 洛谷原题链接 很裸的费用流. 将每个点\(x\)拆成\(x_1,x_2\),并从\(x_1\)向\(x_2\)连一条容量为\(1\),费用为该点的权值的边,以及一条容量为\(+\inf ...
- POJ3422:Kaka's Matrix Travels——题解
http://poj.org/problem?id=3422 题目大意: 从左上角走到右下角,中途取数(数>=0),然后该点的数变为0,求走k的总价值和最大值. ———————————————— ...
- POJ 3422 Kaka's Matrix Travels 【最小费用最大流】
题意: 卡卡有一个矩阵,从左上角走到右下角,卡卡每次只能向右或者向下.矩阵里边都是不超过1000的正整数,卡卡走过的元素会变成0,问卡卡可以走k次,问卡卡最多能积累多少和. 思路: 最小费用最大流的题 ...
随机推荐
- C#泛型简化代码量示例
泛型简化代码量 下是我在项目中通过泛型来简化工作的一个Demo,记录一下: using System; using System.Collections.Generic; namespace My ...
- WPF - MVVM - 如何将ComboBox的Selectchange事件binding到ViewModel
转:http://www.cnblogs.com/mantian/p/3713524.html 将所有的事件,属性,都映射到ViewModel中.好处多多,以后开发尽量用这种模式. 解决方法: 使用S ...
- [2]Telerik Extensions for ASP.NET MVC 中文教程(2)
上一篇文章对Telerik MVC Extensions作了一个大概的介绍,这篇文章将介绍如何将Telerik MVC Extensions添加到项目中.有以下两种方式可以将Telerik MVC E ...
- How to configure SRTM elevations in WorldWind WMS
In this thread I will try to explain how to serve SRTM elevations using NASA WorldWind WMS. ! Import ...
- [转]World Wind学习总结一
WW的纹理,DEM数据,及LOD模型 以earth为例 1. 地形数据: 默认浏览器纹理数据存放在/Cache/Earth/Images/NASA Landsat Imagery/NLT Landsa ...
- Google proto buffer的安装/使用
protobuf安装/使用原本是要在官网上下载的:http://protobuf.googlecode.com/files/protobuf-2.5.0.tar.gz可惜已被墙,幸好有好心人提供了以下 ...
- Android调用基于.net的WebService
在实际开发项目中,有时候会为Android开发团队提供一些接口,一般是以asmx文件的方式来承载.而公布出去的数据一般上都是标准的json数据.但是在实际过程中,发现Android团队那边并不是通过将 ...
- MVC出错案例之一:主外键映射失败
今天在编写DomainModel和DomainMapper,最后放到OnModelCreating中运行的时候,给我抛出了如下错误: One or more validation errors wer ...
- linux实践——内核编程 基础模块
一.内核模块的概念 Linux模块(module)是一些可以作为独立程序来编译的函数和数据类型的集合.内核模块给我们带来的便利是模块本身并不被编译进内核文件,可在内核运行期间动态的安装或卸载.因为如果 ...
- 信息安全系统设计基础实验一:Linux开发环境的配置和使用
北京电子科技学院(BESTI) 实验报告 课程:信息安全系统设计基础 班级:1353 姓名:芦畅 傅冬菁 学号:20135308 20135311 成绩: 指导教师:娄家鹏 ...