[洛谷P2045]方格取数加强版
题目大意:有一个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]方格取数加强版的更多相关文章
- 洛谷 P2045 方格取数加强版【费用流】
题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...
- 洛谷 - P2045 - 方格取数加强版 - 费用流
原来这种题的解法是费用流. 从一个方格的左上走到右下,最多走k次,每个数最多拿走一次. 每次走动的流量设为1,起始点拆点成限制流量k. 每个点拆成两条路,一条路限制流量1,费用为价值相反数.另一条路无 ...
- 洛谷P2045 方格取数加强版(费用流)
题意 题目链接 Sol 这题能想到费用流就不难做了 从S向(1, 1)连费用为0,流量为K的边 从(n, n)向T连费用为0,流量为K的边 对于每个点我们可以拆点限流,同时为了保证每个点只被经过一次, ...
- 洛谷P2045 方格取数加强版 最小费用流
Code: #include<cstdio> #include<cstring> #include<algorithm> #include<queue> ...
- P2045 方格取数加强版
P2045 方格取数加强版 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格 ...
- 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏
P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...
- 洛谷 P2774 方格取数问题 解题报告
P2774 方格取数问题 题目背景 none! 题目描述 在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...
- 洛谷 P1004 方格取数 题解
P1004 方格取数 题目描述 设有 \(N \times N\) 的方格图 \((N \le 9)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字\(0\).如下图所示(见样例): ...
- 洛谷 P1004 方格取数 【多进程dp】
题目链接:https://www.luogu.org/problemnew/show/P1004 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 ...
随机推荐
- ios问题bug收录——1
**[2713:59682] *** Assertion failure in -[MBProgressHUD show:], /Users/lu/Desktop/****/Pods/MBProgr ...
- Ubuntu14.04下Mongodb官网安装部署步骤(图文详解)(博主推荐)
不多说,直接上干货! 在这篇博客里,我采用了非官网的安装步骤,来进行安装.走了弯路,同时,也是不建议.因为在大数据领域和实际生产里,还是要走正规的为好. Ubuntu14.04下Mongodb(离线安 ...
- RabbitMq笔记(2)
今天收获不少,记个笔记. namespace RabbitMQTest { class Program { static void Main(string[] args) { Consumer(); ...
- PostgreSQL+PostGIS
PostGIS简介 PostGIS是对象关系型数据库系统PostgreSQL的一个扩展,PostGIS提供如下空间信息服务功能:空间对象.空间索引.空间操作函数和空间操作符.同时,PostGIS遵循O ...
- codeforces 493 C Vasya and Basketball
题意:给出三分线的值d,分别有两支队伍,如果小于等于d,得2分,如果大于d,得三分,问使得a-b最大时的a,b 一看到题目,就想当然的去二分了----啥都没分出来---55555555 后来才知道不能 ...
- php时间差方法
/** * 时间差计算 * * @param Timestamp $time * @return String Time Elapsed */ function time2Units ($time,$ ...
- eval-Evaluation
eval is a function which evaluates a string as though it were an expression and returns a result; in ...
- ActiveMQ学习笔记(6)----ActiveMQ整合Spring开发
1. 添加依赖 spring 提供了对JMS的支持,需要添加Spring支持jms的包和Spring的核心包,如下: <dependency> <groupId>org.apa ...
- [Python随笔]>>字符串大小写是如何转换的?
首先看下Python的源码 Emmmm,说明是底层的C实现的,所以只放了说明 再看看别人家孩子的博客:https://blog.csdn.net/world6/article/details/6994 ...
- 1044 - Access denied for user 'root'@'%' to database 'xahy-blog' 解决方案二
检查 user 表中'root'@'%' 的grant的权限 select HOST,USER,Grant_priv,Super_priv from mysql.`user`; 可以看到现在这两个权限 ...