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 ...
随机推荐
- "javascript:void(0)"用法
1.window.open(''url'') 2.用自定义函数 <script> function openWin(tag,obj) { obj.target="_blank&q ...
- 黑马程序员-for和foreach
class Program { static void Main(string[] args) { Console.WriteLine("***第一种情况****************** ...
- windows7在局域网中无法映射驱动器问题解决
昨天下班时闲的蛋疼,因电脑比较慢,因此在计算机的[系统配置中]的启动选项下对[启动项目]和[服务]做了误操作,导致在计算机重启之后声卡.显卡.网卡等许多服务禁用,更令人费解的是内网中断了连接,无法访问 ...
- android studio主题设置-笔记3
主题背景设置(就是工具黑色背景还是白色背景),路径:File-Settings-Appearance
- Python Function Note
Python Function Note #汉诺塔问题Python实现 def my_move(n, a, b, c): if n == 1: print(a + ' --> ' + c) el ...
- centos 6.X 安装输入法
1.打开终端 su 输入 密码 yum install "@Chinese Support" 2.接下来是启用中文输入法的操作 系统 ->首选项 ->输入法 3.在弹出 ...
- java对mysql数据库进行单表筛选备份、还原操作
最近在做的一个项目需要对mysql数据库中的单个表格进行备份 其中,一部分表格需要进行筛选备份(例如对最近插入的1000条记录进行备份) 思路:java调用系统命令完成备份操作 假设现在有数据库tes ...
- backbone学习笔记(一)
因为工作的需要,从今天起对backbone的学习过程做下记录. 学习计划: 1.1周看基本知识(2014/1/18-2014/1/25) 2.基本知识总结(2014/1/26) 3.半周按教程写hel ...
- jquery mobile selectmenu下拉菜单
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- 合并JS和CSS
1.先来看看,不用合并js的情况,传输量大 1.1新建一个 [基本]的mvc项目 然后新建一个控制器HomeController,因为js会在很多视图中用到,所以此时我们添加一个视图带布局页Index ...