[洛谷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),我们将其中的某些方格中填入正整数,而其他的方格中则放 ...
随机推荐
- 在Jquery里格式化Date日期时间数据
在Jquery里格式化Date日期时间数据: $(function(){ //当前时间格式化yyyy-MM-dd HH:mm:ss alert(timeStamp2String(new Date(). ...
- HttpWebRequest 表单提交
/// <summary> /// http请求 /// </summary> public static class ZkWebRequestHelp { /// <s ...
- (转载)Android之三种网络请求解析数据(最佳案例)
[置顶] Android之三种网络请求解析数据(最佳案例) 2016-07-25 18:02 4725人阅读 评论(0) 收藏 举报 分类: Gson.Gson解析(1) 版权声明:本文为博主原创 ...
- POJ 2367 Genealogical tree【拓扑排序】
题意:大概意思是--有一个家族聚集在一起,现在由家族里面的人讲话,辈分高的人先讲话.现在给出n,然后再给出n行数 第i行输入的数表示的意思是第i行的子孙是哪些数,然后这些数排在i的后面. 比如样例 5 ...
- Manacher笔记
(其实还是回文自动机好用,毛子真是牛逼) Manacher #include<iostream> #include<cstring> #include<cstdio> ...
- IFC2x3标准阅读
参考地址:西北逍遥-IFC数据模式架构的四个概念层详解说明 1.架构图 IFC模型体系结构由四个层次构成,从下到上依次是 资源层(Resource Layer).核心层(Core Layer).交互层 ...
- mysql 临时表和内存表
查看内存表的最大值: show variables like '%heap%'; mysql> show variables like '%heap%'; +------------------ ...
- 脚本2,从1到99 ,添加用户user1,user2,。。。 user99
脚本2,从1到99 ,添加用户user1,user2,... user99 如果用户user$存在,脚本显示用户存在,否则添加用户,并显示添加用户成功. 脚本如下 [root@localhost ho ...
- 安装了python之后Windows的cmd中cd指令无法转换路径怎么办?
1首先我们看看盘符,我的电脑里有 C D E,F. G盘. 2按下WIN+R键 输入cmd,打开cmd窗口. 3默认路径为用户文档路径,如果想切换到D盘 ,输入cd d: 是不行的. 4:AppDat ...
- SVN学习总结(2)——SVN冲突解决
在我们用VS进行项目合作开发的过程中,SVN的提交控制是至关重要的,大家不可避免的都遇到过SVN冲突的问题,开发的时候,应该认真学习SVN的知识,减少冲突,集中时间放在开发上. 解决冲突有三种方式: ...