题目链接

给一个n*n的矩阵, 从左上角出发, 走到右下角, 然后在返回左上角,这样算两次。 一共重复k次, 每个格子有值, 问能够取得的最大值是多少, 一个格子的值只能取一次, 取完后变为0。

费用流第一题, 将每个格子拆为两个点, u向u'连一条容量为1, 费用为格子的值的边, u向u'再连一条容量为k-1, 费用为0的边。u'向他右边和下边的格子连一条容量为k, 费用为0的边, 跑一遍费用流就可以。

 #include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {, }, {, }, {, -}, {, } };
const int maxn = 2e5+;
int num, head[maxn*], s, t, n, k, nn, dis[maxn], flow, cost, cnt, cap[maxn], q[maxn], cur[maxn], vis[maxn];
struct node
{
int to, nextt, c, w;
node(){}
node(int to, int nextt, int c, int w):to(to), nextt(nextt), c(c), w(w) {}
}e[maxn*];
int spfa() {
int st, ed;
st = ed = ;
mem2(dis);
++cnt;
dis[s] = ;
cap[s] = inf;
cur[s] = -;
q[ed++] = s;
while(st<ed) {
int u = q[st++];
vis[u] = cnt-;
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to, c = e[i].c, w = e[i].w;
if(c && dis[v]>dis[u]+w) {
dis[v] = dis[u]+w;
cap[v] = min(c, cap[u]);
cur[v] = i;
if(vis[v] != cnt) {
vis[v] = cnt;
q[ed++] = v;
}
}
}
}
if(dis[t] == inf)
return ;
cost += dis[t]*cap[t];
flow += cap[t];
for(int i = cur[t]; ~i; i = cur[e[i^].to]) {
e[i].c -= cap[t];
e[i^].c += cap[t];
}
return ;
}
int mcmf() {
flow = cost = ;
while(spfa())
;
return cost;
}
void add(int u, int v, int c, int val) {
e[num] = node(v, head[u], c, -val); head[u] = num++;
e[num] = node(u, head[v], , val); head[v] = num++;
}
void input() {
int x;
for(int i = ; i<n; i++) {
for(int j = ; j<n; j++) {
scanf("%d", &x);
add(i*n+j, i*n+j+nn, , x);
add(i*n+j, i*n+j+nn, k-, );
}
}
add(s, , k, );
add(*nn-, t, k, );
for(int i = ; i<n; i++) {
for(int j = ; j<n; j++) {
for(int k1 = ; k1<; k1++) {
int x = dir[k1][]+i;
int y = dir[k1][]+j;
if(x>=&&x<n&&y>=&&y<n) {
add(i*n+j+nn, x*n+y, k, );
}
}
}
}
}
void init() {
mem1(head);
num = cnt = ;
mem(vis);
}
int main()
{
while(~scanf("%d%d", &n, &k)) {
init();
nn = n*n;
s = *nn, t = s+;
input();
int ans = mcmf();
printf("%d\n", -ans);
}
return ;
}

poj 3422 Kaka's Matrix Travels 费用流的更多相关文章

  1. POJ 3422 Kaka's Matrix Travels(费用流)

    Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6792   Accepted:  ...

  2. POJ 3422 Kaka's Matrix Travels

    Kaka's Matrix Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9567   Accepted:  ...

  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 (K取方格数:最大费用流)

    题意 给出一个n*n大小的矩阵,要求从左上角走到右下角,每次只能向下走或者向右走并取数,某位置取过数之后就只为数值0,现在求解从左上角到右下角走K次的最大值. 思路 经典的费用流模型:K取方格数. 构 ...

  5. [poj] 3422 Kaka's Matrix Travels || 最小费用最大流

    原题 给一个N*N的方阵,从[1,1]到[n,n]走K次,走过每个方格加上上面的数,然后这个格上面的数变为0.求可取得的最大的值. 要求最大值,所以把边权全为负跑最小费用即可.因为只有第一次经过该点的 ...

  6. POJ 3422 Kaka's Matrix Travels K取方格数

    题目:给出n*n的方格矩阵,现在从左上方走m次到右下方,问m次能够获得的最大价值和. 分析:最大费用流.拆点进行限制每个格子只取一次,假设点x拆成 x,xx,右边(假设有)y,yy,下方(假设有)z, ...

  7. POJ 3422 Kaka's Matrix Travels 【最小费用最大流】

    题意: 卡卡有一个矩阵,从左上角走到右下角,卡卡每次只能向右或者向下.矩阵里边都是不超过1000的正整数,卡卡走过的元素会变成0,问卡卡可以走k次,问卡卡最多能积累多少和. 思路: 最小费用最大流的题 ...

  8. POJ 3422 Kaka's Matrix Travels(最小费用最大流)

    http://poj.org/problem?id=3422 题意 : 给你一个N*N的方格,每个格子有一个数字,让你从左上角开始走,只能往下往右走,走过的数字变为0,走K次,问最大能是多大,累加的. ...

  9. POJ 3422 Kaka's Matrix Travels(拆点+最大费用流)题解

    题意:小A从左上角走到右下角,每个格子都有一个价值,经过这个格子就把价值拿走,每次只能往下或往右走,问你走k次最多能拿多少价值的东西. 思路:这里有一个限制条件就是经过之后要把东西拿走,也就是每一格的 ...

随机推荐

  1. Android采用HttpClient下载图片

    在上一章中谈到Android采用HttpURLConnection下载图片,本章使用HttpClient下载图片 HttpURLConnection与HttpClient的差别: HttpClient ...

  2. Spring MVC详细示例实战教程【转】

    一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...

  3. OC 中的block使用

    在iOS的开发过程中,使用块的地方很多也很方便,但是在使用块的过程中要注意内存泄露的问题. 在块创建的时候,会对块内的所有对象的引用计数加一,直到块销毁,所以在使用块的过程中需要我们进行处理,在这里以 ...

  4. sql查询当天数据

    向数据库中添加日期 MS SQL SERVER: NSERT into student(studentid,time1)values('15',getdate()); MY SQLinsert int ...

  5. 【转】iOS隐藏导航条1px的底部横线

    默认情况下会有这条线 第一种方法: 1 2 3 4 5 6 UINavigationBar *navigationBar = self.navigationController.navigationB ...

  6. 如何在一个工作站里创建多个工程(同一个xcode下面创建多个工程)

    第一步,理解: 怎么会有一个xcode下面创建两个工程这一说呢,一个工程代表一个项目,意思就是有两个项目了.错.其实在一个窗口下面并不是两个工程,而是一个workspace 即一个工作站.在工作站里面 ...

  7. .NET软件开发与常用工具清单

    [工欲善其事,必先利其器]软件开发的第一步就是选择高效.智能的工具. 下面列出的工具软件能辅助提高工作效率.  开发类工具 微软.Net平台下的集成开发环境:Visual Studio. Visual ...

  8. php基础知识--文件操作

    文件操作 文件 广义角度: 任何一个在磁盘上可以看到的符号(包含真正的文件及文件夹) 狭义角度: 真实存储数据的载体(不包含文件夹, 如doc文件,txt文件等) 文件操作: 对文件的增删改查 文件分 ...

  9. web编程速度大比拼(nodejs go python)(非专业对比)

    C10K问题的解决,涌现出一大批新框架,或者新语言,那么问题来了:到底谁最快呢?非专业程序猿来个非专业对比. 比较程序:输出Hello World! 测试程序:siege –c 100 –r 100 ...

  10. 《Pointers On C》读书笔记(第四章 语句)

    1.空语句只包含一个分号,它本身并不执行任何任务,其适用的场合是语法要求出现一条完整的语句,但并不需要它执行任何任务. 2.C语言中并不存在专门的“赋值语句”,赋值就是一种操作,在表达式内进行.通过在 ...