题目链接

给一个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. mac下通过xcodebuild使用oclint

    step1 :下载oclint并安装 下载地址: http://oclint.org/downloads.html 选择mac os x或者darwin的包,下载到本地. 文件夹类似以下: oclin ...

  2. iOS 处理方法中的可变參数

    ## iOS 处理方法中的可变參数 近期写了一个自己定义的对话框的demo,想模仿系统的UIAlertView的实现方式.对处理可变參数的时候,遇到了小问题,于是谷歌了一下.写下了处理问题的方法.记录 ...

  3. Python之lxml

    作者:Shane 出处:http://bluescorpio.cnblogs.com lxml takes all the pain out of XML. Stephan Richter lxml是 ...

  4. js中字符串方法

    字符串方法: 1. charAt(索引值)//通过索引值获取字符串中对应的值 例如: var str='sdf123'; alert(str.charAt(0));//结果弹出第一个索引对应的值:s

  5. nginx install

    ./configure --prefix=/home/allen.mh/local/nginx --with-http_ssl_module --with-http_sub_module --with ...

  6. 使用Integer类实现二叉树排序

    class BinaryTree {     class Node {         private Comparable data;         private Node left;      ...

  7. 数组求最大最小值和排序java实现

    public class ArrayDemo05 { public static void main(String[] args) {     int list01[]={67,89,87,69,90 ...

  8. codeforces 546D Soldier and Number Game

    题目链接 这个题, 告诉你a, b的值, 那么只需要求出b到a之间的数, 每个数有多少个因子就可以. 具体看代码, 代码里面有解释 #include<bits/stdc++.h> usin ...

  9. [C语言练习]学生学籍管理系统

    /** * @copyright 2012 Chunhui Wang * * wangchunhui@wangchunhui.cn * * 学生学籍管理系统(12.06) */ #include &l ...

  10. 11-3URLTestDemo实例操作完成URL单元测试

    11-3URLTestDemo 1.File -> New -> Project 在左边模板中选择Visual C#里的Web,对应到的项目类型选择ASP.NET MVC3 Web App ...