POJ3422 Kaka's Matrix Travels 【最大费用最大流】
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 8006 | Accepted: 3204 |
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
题意:有一个NxN的棋盘,小明从左上角開始走到右下角,仅仅能向右和向下走。每一个落子点都有一个非负整数。小明每次经过一个落子点都会将点的值加到sum上,同一时候该点的值清零。问:假设小明走K次的话sum的最大值是多少。同一个点能够走多次。
题解:拆点+费用流。走K次表示最大流为K,求sum最大值表示求最大费用。构图时要将点权拆分成边权,比方点X,拆成X到X'有一条容量为1的边。费用为该点原来的值,再在X到X'间加一条边。容量inf,费用0,然后再用X'跟其它点相连。因为是求最大费用。因此每次增广路时SPFA都要向大松弛。
#include <stdio.h>
#include <string.h>
#include <queue>
#define inf 0x3f3f3f3f
#define maxN 55
#define maxn maxN * maxN * 2
#define maxm maxn * 4
using std::queue; int head[maxn], n, k, id;
struct Node {
int u, v, c, f, next;
} E[maxm];
int dist[maxn], map[maxN][maxN];
int pre[maxn], source, sink;
bool vis[maxn]; void addEdge(int u, int v, int c, int f) {
E[id].u = u; E[id].v = v; E[id].f = f;
E[id].c = c; E[id].next = head[u];
head[u] = id++;
E[id].u = v; E[id].v = u; E[id].f = -f;
E[id].c = 0; E[id].next = head[v];
head[v] = id++;
} void getMap() {
memset(head, -1, sizeof(head));
int i, j, f, pos, down, right; id = 0;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j) {
scanf("%d", &map[i][j]);
pos = i * n + j; right = pos + 1;
down = pos + n;
addEdge(pos, pos + n*n, 1, map[i][j]); // 拆点
addEdge(pos, pos + n*n, inf, 0);
if(i != n - 1) {
addEdge(pos + n*n, down, inf, 0);
}
if(j != n - 1) {
addEdge(pos + n*n, right, inf, 0);
}
}
source = 2 * n * n; sink = source + 1;
map[n][0] = map[n][1] = 0;
addEdge(source, 0, k, 0);
addEdge(source - 1, sink, k, 0);
} bool SPFA(int start, int end) {
memset(pre, -1, sizeof(pre));
memset(vis, 0, sizeof(vis));
memset(dist, -1, sizeof(dist));
queue<int> Q; Q.push(start);
int u, v, i; vis[start] = 1; dist[start] = 0;
while(!Q.empty()) {
u = Q.front(); Q.pop(); vis[u] = 0;
for(i = head[u]; i != -1; i = E[i].next) {
v = E[i].v;
if(E[i].c && dist[v] < dist[u] + E[i].f) {
dist[v] = dist[u] + E[i].f;
pre[v] = i;
if(!vis[v]) {
vis[v] = 1; Q.push(v);
}
}
}
}
return dist[end] != -1;
} void solve() {
int sum = 0, i, u, v, minCut;
while(SPFA(source, sink)) {
minCut = inf;
for(i = pre[sink]; i != -1; i = pre[E[i].u]) {
if(minCut > E[i].c) minCut = E[i].c;
}
sum += minCut * dist[sink];
for(i = pre[sink]; i != -1; i = pre[E[i].u]) {
E[i].c -= minCut;
E[i^1].c += minCut;
}
}
printf("%d\n", sum);
} int main() {
// freopen("stdin.txt", "r", stdin);
while(scanf("%d%d", &n, &k) == 2) {
getMap();
solve();
}
return 0;
}
POJ3422 Kaka's Matrix Travels 【最大费用最大流】的更多相关文章
- POJ 3422 Kaka's Matrix Travels(费用流)
POJ 3422 Kaka's Matrix Travels 题目链接 题意:一个矩阵.从左上角往右下角走k趟,每次走过数字就变成0,而且获得这个数字,要求走完之后,所获得数字之和最大 思路:有点类似 ...
- POJ训练计划3422_Kaka's Matrix Travels(网络流/费用流)
解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次仅仅能向右和向下走,走到一个格子上加上格子的数,能够走k次.问最大的和是多少. 思路: 建图:每一个格子掰成两个点,分别叫" ...
- POJ 3422 Kaka's Matrix Travels (最小费用最大流)
POJ 3422 Kaka's Matrix Travels 链接:http://poj.org/problem? id=3422 题意:有一个N*N的方格,每一个方格里面有一个数字.如今卡卡要从左上 ...
- poj Kaka's Matrix Travels
Kaka's Matrix Travels 题目: 给出一个矩阵.求仅仅能向下或者向右的情况下能得到的最大和.一般的是指遍历一次,而这个是能够反复走K次.每经过一次后就把该点设为0.求最大和. 算法: ...
- [poj] 3422 Kaka's Matrix Travels || 最小费用最大流
原题 给一个N*N的方阵,从[1,1]到[n,n]走K次,走过每个方格加上上面的数,然后这个格上面的数变为0.求可取得的最大的值. 要求最大值,所以把边权全为负跑最小费用即可.因为只有第一次经过该点的 ...
- POJ3422 Kaka's Matrix Travels 【费用流】*
POJ3422 Kaka's Matrix Travels Description On an N × N chessboard with a non-negative number in each ...
- 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(最小费用最大流问题)
/* poj3422 Kaka's Matrix Travels 不知道 k次 dp做为什么不对??? 看了大牛的代码,才知道还可以这样做! 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序 ...
- Matrix Again(最大费用最大流)
Matrix Again Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Tota ...
随机推荐
- 使用top工具,找出消耗CPU 较多的进程
1.使用top工具,找出消耗CPU 较多的进程 [oracle@cuug ~]$ top top - 10:48:27 up 23:15, 4 users, load average: 1.09, ...
- iOS真机测试种可能遇到的问题
1. Reason- image not found 用模拟器是没有问题的,不过在真机好像是有问题,不确定是否是所有机型. 崩溃日志 1 2 3 4 5 dyld: Library not l ...
- Ubuntu12.04安装insight-6.8
insight是在Linux下一个比较好用的GDB的前端 insight首页:http://sourceware.org/insight/index.php 在这里下载源码:insight-6.8.t ...
- [转]Delphi 关键字详解
全文链接地址:http://www.cnblogs.com/del/archive/2008/06/23/1228562.html
- JavaScript 目标装配式编程(Target Assemble Programming)
TAP概述 脚本中一切皆对象,若还以传统模式思考编程模式,那简直是对不起脚本解释器的强大支持:我们应该以最接近人类操作方式的来表达人的意图. 更接近工作实践的方式,比如游戏中,一个人物一个角色,人物的 ...
- URL编码详解
escape,encodeURI,encodeURIComponent. 据说还有base64,但会被 = 来补. 待编辑.
- 关闭C#主窗体弹出是否关闭对话框
在开发系统时,常常有这样一个问题,就是当关闭主窗体,也即退出系统时,如果想提示是否关闭,以免误操作,可以在主窗体的Main_FormClosing事件中添加一个对话框,代码如下: private vo ...
- 关于PHP参数的引用传递和值传递
如果希望编写一个名为increment()的函数来增加一个变量的值,我们可能会按如下方式编写这个函数: 这段代码是没有用的.下面测试代码的输出结果是“10”. $value 的内容没有被修改.这要归因 ...
- uva10561 - Treblecross
Treblecross is a two player game where the goal is to get three `X' in a row on a one-dimensional bo ...
- 从零开始学Sketch——进阶篇-b
从零开始学Sketch——进阶篇 Sketch是一款矢量绘图应用,而矢量绘图无疑是目前进行网页.图标以及界面设计的最好方式. 在初识了Sketch的界面布局和基础工具之后,我们就可以开始进入高阶的Sk ...