http://www.wikioi.com/problem/1227

裸题,拆点,容量为1,费用为点权的负数(代表只能取一次)。再在拆好的两个点连边,容量为oo,费用为0。(代表能取0)

然后向右和下连边,容量我oo,费用为0

最后跑一次最小费用,取绝对值就是答案。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << #x << " = " << x << endl
#define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; } const int N=5500, M=1000000, oo=~0u>>1;
int ihead[N], cnt=1, d[N], p[N], n, k, vis[N], q[N], front, tail;
struct ED { int from, to, cap, w, next; } e[M];
inline void add(const int &u, const int &v, const int &c, const int &w) {
e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].from=u; e[cnt].cap=c; e[cnt].w=w;
e[++cnt].next=ihead[v]; ihead[v]=cnt; e[cnt].to=u; e[cnt].from=v; e[cnt].cap=0; e[cnt].w=-w;
}
inline const bool spfa(const int &s, const int &t) {
for1(i, 0, t) d[i]=1000000000, vis[i]=0;
vis[s]=1; d[s]=front=tail=0; q[tail++]=s;
int u, v, i;
while(front!=tail) {
u=q[front++]; if(front==N) front=0;
for(i=ihead[u]; i; i=e[i].next) if(e[i].cap && d[v=e[i].to]>d[u]+e[i].w) {
d[v]=d[u]+e[i].w; p[v]=i;
if(!vis[v]) {
vis[v]=1, q[tail++]=v;
if(tail==N) tail=0;
}
}
vis[u]=0;
}
return d[t]!=1000000000;
}
int mcf(const int &s, const int &t) {
int ret=0, f, u;
while(spfa(s, t)) {
for(f=oo, u=t; u!=s; u=e[p[u]].from) f=min(f, e[p[u]].cap);
for(u=t; u!=s; u=e[p[u]].from) e[p[u]].cap-=f, e[p[u]^1].cap+=f;
ret+=d[t]*f;
}
return ret;
}
int main() {
read(n); read(k);
int s=0, t=n*n*2+1, c, now, pw=n*n;
for1(i, 1, n) for1(j, 1, n) {
read(c); now=(i-1)*n+j;
add(now, now+pw, 1, -c); add(now, now+pw, oo, 0);
if(i<n) add(now+pw, now+n, oo, 0);
if(j<n) add(now+pw, now+1, oo, 0);
}
add(s, 1, k, 0); add(n*n*2, t, k, 0);
printf("%d\n", -mcf(s, t));
return 0;
}

题目描述 Description

给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大

输入描述 Input Description

第一行两个数n,k(1<=n<=50, 0<=k<=10)

接下来n行,每行n个数,分别表示矩阵的每个格子的数

输出描述 Output Description

一个数,为最大和

样例输入 Sample Input

3 1

1 2 3

0 2 1

1 4 2

样例输出 Sample Output

11

数据范围及提示 Data Size & Hint

1<=n<=50, 0<=k<=10

【wikioi】1227 方格取数 2(费用流)的更多相关文章

  1. Codevs 1227 方格取数 2(费用流)

    1227 方格取数 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 查看运行结果 题目描述 Description 给出一个n*n的矩阵,每一格有一个非负整数 ...

  2. 洛谷 - P2045 - 方格取数加强版 - 费用流

    原来这种题的解法是费用流. 从一个方格的左上走到右下,最多走k次,每个数最多拿走一次. 每次走动的流量设为1,起始点拆点成限制流量k. 每个点拆成两条路,一条路限制流量1,费用为价值相反数.另一条路无 ...

  3. 洛谷P2045 方格取数加强版(费用流)

    题意 题目链接 Sol 这题能想到费用流就不难做了 从S向(1, 1)连费用为0,流量为K的边 从(n, n)向T连费用为0,流量为K的边 对于每个点我们可以拆点限流,同时为了保证每个点只被经过一次, ...

  4. LG2045 方格取数加强版 费用流

    问题描述 LG2045 题解 费用流. 套路拆点,把\((i,j)\)拆为两个点,在这两个点之间连边:一条边流量为\(1\),费用为\(a_{i,j}\),另一条边为流量为\(INF\),费用为\(0 ...

  5. 【费用流】【CODEVS】1227 方格取数2

    [算法]最小费用最大流(费用流) [题解] 费用流:http://www.cnblogs.com/onioncyc/p/6496532.html 本题构图: 在有限的k次行走中尽可能多的拿到数字,明显 ...

  6. codevs 1227 方格取数 2

    Description 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来, ...

  7. poj3422K方格取数——最大费用最大流

    题目:http://poj.org/problem?id=3422 最大费用最大流: 拆点,在自点之间连两条边,一条容量为1,边权为数字:一条容量为k-1,边权为0:表示可以走k次,只有一次能取到数字 ...

  8. HDU 1565&1569 方格取数系列(状压DP或者最大流)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  9. LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

    #6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

随机推荐

  1. 如何高效利用GitHub

    是Github,让社会化编程成为现实.本文尝试谈谈GitHub的文化.技巧与影响. Q1:GitHub是什么 Q2:GitHub风格 Q3: 在GitHub,如何跟牛人学习 Q4: 享受纯粹的写作与演 ...

  2. 在windows下用cygwin和eclipse搭建cocos2dx(2.1.4)的android开发环

    一.准备工作 需要下载和安装以下内容,请根据自己的操作系统选择x86和x64(我的是64位win7,我就拿64位说事) 1.jdk-7u25-windows-x64.exe(下载完后直接安装,一直下一 ...

  3. 如何用BMFont制作图片字

    1: 运行程序,单击鼠标左键点亮相应位置的字母,比如:0.1.2./ 等2: 选择 Edit->Open Image Manager.弹出一个“Image Manager" 对话框3: ...

  4. c++11之bind

    std::bind是个c++推出的新的特性,非常有用,让你写起来率试不爽. #include <iostream> using namespace std; #include <fu ...

  5. GPL协议的MySQL数据库

    网络上多数朋友担心甲骨文会对MySQL软件采用收费模式,多数朋友也不清楚MySQL开源到底是什么模式,开源=免费嘛?是很多的疑问?MySQL是遵守双重协议的,一个是GPL授权协议,一个是商用授权协议( ...

  6. 【JAVA、C++】LeetCode 007 Reverse Integer

    Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 解题思路:将数字 ...

  7. Java的++自增

    记得大学刚开始学C语言时,老师就说:自增有两种形式,分别是i++和++i,i++表示的是先赋值后加1,++i是先加1后赋值,这样理解了很多年也没出现问题,直到遇到如下代码,我才怀疑我的理解是不是错了: ...

  8. [Android Pro] 利用tcpdump和wireshark对android网络请求进行分析

    一: tcpdump操作流程 1. 手机要有root权限 2. 下载tcpdump   http://www.strazzere.com/android/tcpdump 3. adb push c:\ ...

  9. git merge和个git rebase的区别

    http://stackoverflow.com/questions/16666089/whats-the-difference-between-git-merge-and-git-rebase/16 ...

  10. Entity Framework 使用

    1.EF中Include方法的使用使用Include方法,告诉EF连接查询哪个外键属性,生成Inner join连接 //必须引用using System.Data.Entity;才能用Include ...