题目大意:有一个n*n的矩阵,每个格子有一个非负整数,规定一个人从(1,1)开始,只能往右或下走,走到(n,n)为止,并把沿途的数取走,取走后数变为0。这个人共取n次,求取得的数的最大总和。

解题思路:由于取多少次不确定,所以不能用dp。

我们发现,一个格子只能从左边或上面走来,且数只能取到一次,那么我们可以把此题转化为最大费用最大流问题。首先拆点,将一个点拆成x和y,然后从x到y连一条容量为1,流量为x(x为这格的数)的边,然后再连一条容量为inf,费用为0的边,这样即可保证一个点可以走多次,而数只能取一次。然后连接a和b时,从a的y向b的x连一条容量为inf,费用为0的边。最后跑最大费用最大流即可。

实现时对于(i,j),我们把这个点的x编号为$(i-1)*n+j$,y编号为$(i-1)*n+j+n^2$即可。

以下为EK算法代码。

C++ Code:

#include<cstdio>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 1000000
struct edge{
int from,to,cap,cost,nxt;
}e[N];
int n,k,dis[N],a[N],pree[N],head[N],cnt;
bool vis[N];
queue<int>q;
inline void addedge(int from,int to,int cap,int cost){
e[++cnt]=(edge){from,to,cap,cost,head[from]};
head[from]=cnt;
e[++cnt]=(edge){to,from,0,-cost,head[to]};
head[to]=cnt;
}
bool spfa(int s,int t,int& flow,int& cost){
memset(pree,0,sizeof(pree));
memset(a,0x3f,sizeof(a));
memset(dis,200,sizeof(dis));
memset(vis,0,sizeof(vis));
vis[s]=1;
dis[s]=0;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=e[i].nxt){
if(e[i].cap>0&&dis[e[i].to]<dis[u]+e[i].cost){
dis[e[i].to]=dis[u]+e[i].cost;
pree[e[i].to]=i;
if(a[u]>e[i].cap)a[e[i].to]=e[i].cap;else a[e[i].to]=a[u];
if(!vis[e[i].to]){
vis[e[i].to]=1;
q.push(e[i].to);
}
}
}
}
if(dis[t]<1)return false;
flow+=a[t];
cost+=a[t]*dis[t];
for(int i=t;i!=s;i=e[pree[i]].from){
e[pree[i]].cap-=a[t];
e[pree[i]^1].cap+=a[t];
}
return true;
}
int main(){
cnt=1;
scanf("%d%d",&n,&k);
int m=n*n;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
int x;
scanf("%d",&x);
addedge((i-1)*n+j,(i-1)*n+j+m,inf,0);
addedge((i-1)*n+j,(i-1)*n+j+m,1,x);
if(i>1){
addedge((i-2)*n+j+m,(i-1)*n+j,inf,0);
}
if(j>1){
addedge((i-1)*n+j-1+m,(i-1)*n+j,inf,0);
}
if(i==1&&j==1){
addedge(0,1,inf,0);
}
}
}
int flow=0,cost=0;
while(k--)
if(!spfa(0,m<<1,flow,cost))break;
printf("%d\n",cost);
return 0;
}

[洛谷P2045]方格取数加强版的更多相关文章

  1. 洛谷 P2045 方格取数加强版【费用流】

        题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...

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

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

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

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

  4. 洛谷P2045 方格取数加强版 最小费用流

    Code: #include<cstdio> #include<cstring> #include<algorithm> #include<queue> ...

  5. P2045 方格取数加强版

    P2045 方格取数加强版 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格 ...

  6. 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏

    P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...

  7. 洛谷 P2774 方格取数问题 解题报告

    P2774 方格取数问题 题目背景 none! 题目描述 在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...

  8. 洛谷 P1004 方格取数 题解

    P1004 方格取数 题目描述 设有 \(N \times N\) 的方格图 \((N \le 9)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字\(0\).如下图所示(见样例): ...

  9. 洛谷 P1004 方格取数 【多进程dp】

    题目链接:https://www.luogu.org/problemnew/show/P1004 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 ...

随机推荐

  1. fatal error C1003: error count exceeds number; stopping compilation解决方法

    [error]C1003: error count exceeds 100; stopping compilation ...winnt.h 在项目工程中添加#include<windows.h ...

  2. linux ps 命令查看进程状态

    显示其他用户启动的进程(a) 查看系统中属于自己的进程(x) 启动这个进程的用户和它启动的时间(u) 使用“date -s”命令来修改系统时间 比如将系统时间设定成1996年6月10日的命令如下. # ...

  3. PHP简介 变量 输出

    一.PHP概念 Hypertext Preprocessor 超文本预处理器,是一种开源脚本语言,语法吸收了C语言,Java,Perl的特点,用于web开发领域, PHP是将程序嵌入到Html文档中执 ...

  4. 企业微信H5支付返回不到自己指定的结果页面

    项目:vue做的H5项目,嵌入到企业微信里 发现的问题:支付完成后的跳转页面 跳转不到自己指定的页面 问题在于:调支付接口时,redirectUrl: document.location.protoc ...

  5. canvas 连线曲线图

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta name=& ...

  6. luogu P3765 总统选举(线段树维护摩尔投票+平衡树)

    这题需要一个黑科技--摩尔投票.这是一个什么东西?一个神奇的方法求一个序列中出现次数大于长度一半的数. 简而言之就是同加异减: 比如有一个代表投票结果的序列. \[[1,2,1,1,2,1,1]\] ...

  7. yum-config-manager --add-repo=

    [root@server0 yum.repos.d]# yum-config-manager --add-repo=ftp://192.168.31.121/centos7u4Loaded plugi ...

  8. 紫书 例题 11-13 UVa 10735(混合图的欧拉回路)(最大流)

    这道题写了两个多小时-- 首先讲一下怎么建模 我们的目的是让所有点的出度等于入度 那么我们可以把点分为两部分, 一部分出度大于入度, 一部分入度大于出度 那么显然, 按照书里的思路,将边方向后,就相当 ...

  9. 项目集成Hudson+SonarQube出现的一个问题

    [ERROR] No plugin found for prefix 'sonar' in the current project and in the plugin groups [org.mort ...

  10. spring中操作mysql数据库

    就是在spring中,对mysql数据库进行增删改查的样例,很easy. 文件结构 maven的pom.xml文件,里面用到的几个很重要的jar包都有 <project xmlns=" ...