POJ3422 Kaka's Matrix Travels 【费用流】*
POJ3422 Kaka’s Matrix Travels
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
题意大概就是给你一个n*n的矩形,每一个方格中有一个权值,定义一次行走是从左上角走到右下角,而且每一次移动只能向右边或者下边移动,现在我们要行走k次,并使经过的点集的和最大(每个点值计算一次)
我们很容易想到把每个点的权值作为这个点某种意义上的费用(因为只能计算一次,后面会介绍建图方法),然后我们想最大化这个费用,所以对于这种问题我们可以见图的时候将边权取相反数,然后再跑出最小费用大流的时候将费用取相反数,不难发现这个时候的费用是最大化的
然后我们怎么处理一个节点的边权只能计算一次这个条件呢?
不妨这样思考,我们把一个点i拆成两个点i" role="presentation">ii和i+n∗n" role="presentation">i+n∗ni+n∗n,在i" role="presentation">ii和i+n∗n" role="presentation">i+n∗ni+n∗n之间连接两条弧:
1:一条容量为1,费用为负边权
2:一条容量为k-1,费用为0
我们可以很容易得到如果有流量经过弧2,一定有流量经过弧1,不然就不满足最小费用的性质
又对于两个节点i" role="presentation">ii和j" role="presentation">jj,满足j在i的下边或右边,即i" role="presentation">ii可以到达j" role="presentation">jj,那么我们可以把i+n∗n" role="presentation">i+n∗ni+n∗n连接到j" role="presentation">jj,这样流经i" role="presentation">ii的流量就可以流到j" role="presentation">jj了
现在我们只需要保证源点S流到第一个节点(坐标(1,1))的容量是k就好了
整理一下构图思路:
1 从S" role="presentation">SS连接到第一个节点(1,1)" role="presentation">(1,1)(1,1),容量为k
2 从i" role="presentation">ii到i+n∗n" role="presentation">i+n∗ni+n∗n连接两条弧:
" role="presentation"> 1:一条容量为1,费用为负边权
" role="presentation"> 2:一条容量为k-1,费用为0
3 对于i" role="presentation">ii到可以到达的j" role="presentation">jj连接一条从i+n∗n" role="presentation">i+n∗ni+n∗n到j" role="presentation">jj的边
4 从最后一个节点(n,n)" role="presentation">(n,n)(n,n)连接到汇点T" role="presentation">TT
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define N 100010
#define INF 0x3f3f3f3f
struct Edge{
int u,v,cap,flow,cost;
Edge(int xu,int xv,int xcap,int xflow,int xcost){
u=xu;v=xv;cap=xcap;flow=xflow;cost=xcost;
}
};
struct MCMF{
int s,t,f[N],p[N],d[N];
bool inq[N];
vector<Edge> E;
vector<int> G[N];
void add(int u,int v,int cap,int cost){
E.push_back(Edge(u,v,cap,0,cost));
E.push_back(Edge(v,u,0,0,-cost));
int m=E.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
bool SPFA(int &flow,int &cost){
memset(inq,0,sizeof(inq));
memset(d,0x3f,sizeof(d));
queue<int> Q;Q.push(s);
d[s]=0;f[s]=INF;
while(!Q.empty()){
int u=Q.front();Q.pop();
inq[u]=0;
for(int i=0;i<G[u].size();i++){
Edge e=E[G[u][i]];
if(d[e.v]>d[u]+e.cost&&e.cap>e.flow){
d[e.v]=d[u]+e.cost;
p[e.v]=G[u][i];
f[e.v]=min(f[u],e.cap-e.flow);
if(!inq[e.v]){
Q.push(e.v);
inq[e.v]=1;
}
}
}
}
if(d[t]==INF)return false;
flow+=f[t];cost+=f[t]*d[t];
int u=t;
while(u!=s){
E[p[u]].flow+=f[t];
E[p[u]^1].flow-=f[t];
u=E[p[u]].u;
}
return true;
}
int Min_cost_Max_flow(){
int flow=0,cost=0;
while(SPFA(flow,cost));
return cost;
}
}mcmf;
int n,k;
int g[100][100];
int Index(int x,int y){return (x-1)*n+y;}
int main(){
scanf("%d%d",&n,&k);
mcmf.s=0;mcmf.t=2*n*n+1;
mcmf.add(0,1,k,0);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&g[i][j]);
int tmp=Index(i,j);
mcmf.add(tmp,tmp+n*n,1,-g[i][j]);
mcmf.add(tmp,tmp+n*n,k-1,0);
if(i<n){
int tmp1=Index(i+1,j);
mcmf.add(tmp+n*n,tmp1,INF,0);
}
if(j<n){
int tmp1=Index(i,j+1);
mcmf.add(tmp+n*n,tmp1,INF,0);
}
}
}
mcmf.add(2*n*n,2*n*n+1,k,0);
printf("%d",-mcmf.Min_cost_Max_flow());
return 0;
}
POJ3422 Kaka's Matrix Travels 【费用流】*的更多相关文章
- 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 费用流
题目链接 给一个n*n的矩阵, 从左上角出发, 走到右下角, 然后在返回左上角,这样算两次. 一共重复k次, 每个格子有值, 问能够取得的最大值是多少, 一个格子的值只能取一次, 取完后变为0. 费用 ...
- poj3422 Kaka's Matrix Travels(最小费用最大流问题)
/* poj3422 Kaka's Matrix Travels 不知道 k次 dp做为什么不对??? 看了大牛的代码,才知道还可以这样做! 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序 ...
- POJ3422 Kaka's Matrix Travels
描述 On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels wi ...
- POJ 3422 Kaka's Matrix Travels(费用流)
Kaka's Matrix Travels Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6792 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 (K取方格数:最大费用流)
题意 给出一个n*n大小的矩阵,要求从左上角走到右下角,每次只能向下走或者向右走并取数,某位置取过数之后就只为数值0,现在求解从左上角到右下角走K次的最大值. 思路 经典的费用流模型:K取方格数. 构 ...
- [poj] 3422 Kaka's Matrix Travels || 最小费用最大流
原题 给一个N*N的方阵,从[1,1]到[n,n]走K次,走过每个方格加上上面的数,然后这个格上面的数变为0.求可取得的最大的值. 要求最大值,所以把边权全为负跑最小费用即可.因为只有第一次经过该点的 ...
- POJ3422或洛谷2045 Kaka's Matrix Travels
POJ原题链接 洛谷原题链接 很裸的费用流. 将每个点\(x\)拆成\(x_1,x_2\),并从\(x_1\)向\(x_2\)连一条容量为\(1\),费用为该点的权值的边,以及一条容量为\(+\inf ...
随机推荐
- Dive into Spring framework -- 搭建spring 源码的开发环境
spring是一个类之间依赖的管理容器,大家都知道,但我们中很多人都仅仅停留在使用的层面,但spring本身具有极大的研究价值,所以在使用了几年spring之后,还是想深入的探究一下其根源.记录于此, ...
- Vue 备
<div id="app"> <span :class='{red:addClass}'>jam</span> </div> < ...
- Unity 和 3DMAx
3DMax转换成DAE模式才会有纹理信息.
- zookeeper常见错误
1.在注册中心找不到对应的服务 这种错误是服务层代码没有成功注册到注册中心导致,请检查一下你的服务层代码是否添加了@service注解,并且该注解的包一定是com.alibaba.dubbo.conf ...
- Java中如何获取多维数组的长度
在程序处理中遍历数组是一种很常见的操作,但遍历数组时,我们需要知道数组各维度的长度(一维数组除外,for each 可以遍历),下面举例说明如何求多维数组的长度. 一维 : int [] array ...
- HTTP下载图片
网上有专门写的http下载的C++代码,但是我发现windows自带的http下载,一行代码就搞定,非常简单,目前为止使用正常. 首先包含头文件和lib文件 #include <urlmon.h ...
- Python 常用 PEP8 编码规范
Python 常用 PEP8 编码规范 代码布局 缩进 每级缩进用4个空格. 括号中使用垂直隐式缩进或使用悬挂缩进. EXAMPLE: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
- js中的执行环境及作用域
最近在面试时被问到了对作用域链的理解,感觉当时回答的不是很好,今天就来说说js中的作用域链吧. 首先来说说js中的执行环境,所谓执行环境(有时也称环境)它是JavaScript中最为重要的一个概念.执 ...
- JavaScript数字和字符串转换示例
http://www.jb51.net/article/48465.htm 1. 数字转换为字符串 a. 要把一个数字转换为字符串,只要给它添加一个空的字符串即可: 复制代码代码如下: var n = ...
- 那如何判断页面是在移动端还是PC端打开的
网上有很多方法,写的或难或简单,实际上一行代码就够了. window.location.href = /Android|webOS|iPhone|iPod|BlackBerry/i.test(navi ...