P2045 方格取数加强版题解
题目链接:P2045 方格取数加强版 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目:
出一个 n*n 的矩阵,每一格有一个非负整数 A{i,j}且A{i,j} <=10^3 现在从 (1,1) 出发,可以往右或者往下走,最后到达 (n,n),每达到一格,把该格子的数取出来,该格子的数就变成 0,这样一共走 K 次,现在要求 K 次所达到的方格的数的和最大。
解析:
一次方格取数原题是一个四位dp,但走k次的限制很难用dp在图上转移。
因为我们看到题目对每条边有限制,考虑用网络流,拆点建图来满足条件。
拆点可以得到两条边,(i,j)的入点向(i,j)的出点连一条费用为-1*(i,j)的值,流量限制为1(乘-1的原因是我们只能算最小费用最大流,这道题最大费用最大流,所以将费用取为负数,就可以做了),以及一条(i,j)的入点向(i,j)的出点连一条费用为0,流量限制为k-1的边。
同时由题意可知,(i,j)的出点向(i,j+1)和(i+1,j)连一条边,边的费用为0,流量限制为k。
再由网络流的性质,建超级源点向起点的入点连边和终点的出点向汇点连边。这些边的费用为0,流量限制为k,仅仅意味联通。
最后跑最小费用最大流即可
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
const int M=300010;
const int INF=2139062143;
int n,k,dis[N],pre[N],vis[N],flow[N],go[M],nxt[M],hd[N],jz[M],fl[M],tot=1;
int id(int x,int y)
{
return (x-1)*n+y;
}
bool spfa(int s,int t)
{
memset(dis,0x7f,sizeof(dis));
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(s);
dis[s]=0;
vis[s]=1;
flow[s]=INF;
while(!q.empty())
{
int u=q.front();q.pop();
vis[u]=0;
for(int i=hd[u];i;i=nxt[i])
{
int v=go[i];
if(fl[i]==0)continue;
if(fl[i]>0&&dis[v]>dis[u]+jz[i])
{
dis[v]=dis[u]+jz[i];
flow[v]=min(flow[u],fl[i]);
pre[v]=i;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
if(dis[t]==INF)return 0;
return 1;
}
long long ans=0,maxflow;
void zdfy(int s,int t)
{
while(spfa(s,t))//图s,t是否联通
{
maxflow+=flow[t];
ans+=dis[t]*flow[t];//一趟的价值为流量乘从s开始走的边的价值
int x=t;
while(x!=s)
{
int las=pre[x];
fl[las]-=flow[t];//注意流量只消耗了flow[t]
fl[las^1]+=flow[t];
x=go[las^1];
}
}
}
void add(int x,int y,int j,int f)
{
nxt[++tot]=hd[x];go[tot]=y,jz[tot]=j,fl[tot]=f,hd[x]=tot;
nxt[++tot]=hd[y];go[tot]=x,jz[tot]=-j,fl[tot]=0,hd[y]=tot;
return ;
}//dinic算法要反向边
int main()
{
scanf("%d%d",&n,&k);
int s=0,t=2*n*n+1;
add(s,id(1,1),0,k);
add(id(n,n)+n*n,t,0,k);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int x;scanf("%d",&x);
add(id(i,j),id(i,j)+n*n,-x,1);
add(id(i,j),id(i,j)+n*n,0,INF);
if(i<n)add(id(i,j)+n*n,id(i+1,j),0,INF);
if(j<n)add(id(i,j)+n*n,id(i,j+1),0,INF);
}
//建图
zdfy(s,t);
printf("%lld\n",-1*ans);//答案取反
return 0;
}
P2045 方格取数加强版题解的更多相关文章
- P2045 方格取数加强版
P2045 方格取数加强版 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格 ...
- 洛谷 P2045 方格取数加强版【费用流】
题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...
- P2045 方格取数加强版 最大费用最大流
$ \color{#0066ff}{ 题目描述 }$ 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每 ...
- [洛谷P2045]方格取数加强版
题目大意:有一个n*n的矩阵,每个格子有一个非负整数,规定一个人从(1,1)开始,只能往右或下走,走到(n,n)为止,并把沿途的数取走,取走后数变为0.这个人共取n次,求取得的数的最大总和. 解题思路 ...
- 洛谷 - P2045 - 方格取数加强版 - 费用流
原来这种题的解法是费用流. 从一个方格的左上走到右下,最多走k次,每个数最多拿走一次. 每次走动的流量设为1,起始点拆点成限制流量k. 每个点拆成两条路,一条路限制流量1,费用为价值相反数.另一条路无 ...
- bzoj P2045 方格取数加强版【最大费用最大流】
今天脑子不太清醒,把数据范围看小了一直TTTTLE-- 最大费用最大流,每个格子拆成两个(x,y),(x,y)',(x,y)向(x,y)'连一条费用a[x][y]流量1的边表示选的一次,再连一条费用0 ...
- 洛谷P2045 方格取数加强版(费用流)
题意 题目链接 Sol 这题能想到费用流就不难做了 从S向(1, 1)连费用为0,流量为K的边 从(n, n)向T连费用为0,流量为K的边 对于每个点我们可以拆点限流,同时为了保证每个点只被经过一次, ...
- 【Luogu】P2045方格取数加强版(最小费用最大流)
题目链接 通过这题我学会了引诱算法的行为,就是你通过适当的状态设计,引诱算法按照你想要它做的去行动,进而达到解题的目的. 最小费用最大流,首先将点拆点,入点和出点连一条费用=-权值,容量=1的边,再连 ...
- 洛谷P2045 方格取数加强版 最小费用流
Code: #include<cstdio> #include<cstring> #include<algorithm> #include<queue> ...
- [luogu_P2045]方格取数加强版
[luogu_P2045]方格取数加强版 试题描述 给出一个 \(n \times n\) 的矩阵,每一格有一个非负整数 \(A_{i,j},(A_{i,j} \le 1000)\) 现在从 \((1 ...
随机推荐
- SpringMVC学习二(日期参数/数据保存/重定向)
接受的参数为日期类型 controller进行数据保存 Controller如何进行重定向跳转 1.对于前端页面传来日期类型的数据时如何进行处理,有两种方法 1.1在对应的Controller中插入代 ...
- goland dlv在远程linux里运行代码开发,并debug调适
一.配置好ssh自动同步代码 参考下面连接: https://www.cnblogs.com/haima/p/13257524.html 二.配置devbug监听运行 GO Remote 填写配置 l ...
- SpringBoot-RSA加密
前言 最近由于工作业务的需要,需要对指定的字段信息进行非对称加解密:由于需要加密的内容过于庞大:自己执行程序会出现:Data must not be longer than 117 bytes 的异常 ...
- MySQL面试必备二之binlog日志
本文首发于公众号:Hunter后端 原文链接:MySQL面试必备二之binlog日志 关于 binlog,常被问到几个面试问题如下: binlog 是什么 binlog 都记录什么数据 binlog ...
- JDK源码阅读-------自学笔记(八)(数组演示冒泡排序和二分查找)
冒泡排序 算法 比较相邻的元素.如果第一个比第二个大,就交换他们两个 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数 针对所有的元素重复以上的步骤,除 ...
- 前后端分离项目集成PageOffice——实现在线编辑Word文件的版本控制
PageOffice本身提供了SaveFilePage的js方法,但是由于该方法不支持代理且不能跨域导致在前后端分离项目中无法使用 功能:实现三个按钮分别保存不同版本的文件 1.PageOffice可 ...
- C++ Virtual Functions
Virtual这个关键字在多态中扮演一个绝对重要的角色,只要member functions声明的前面加上virtual的关键字,他就会成为 Virtual member functions.任何一个 ...
- 无需重新学习,使用 Kibana 查询/可视化 SLS 数据
1. 场景 现在通过 SLS 的 ES 兼容能力,可以很方便地实现用 Kibana 来查询和可视化 SLS 的数据.对于从 ES 迁移到 SLS 的用户可以继续保留原来的 Kibana 使用习惯.下面 ...
- git解决Enter passphrase for key ‘/root/.ssh/id_rsa’: 重复输入密码问题
删除方法: ssh-keygen -p 这里只是删除密码 ssh的pub不会改变. 屏幕快照 2019-12-20 下午4.11.05.png Enter file in which the ...
- IDEA使用——常用配置
一. 设置鼠标悬停代码提示 二. 设置Ctrl+滚乱调整字体大小 三. 设置自动导包(不设置自动导包,我们也可以通过Alt+Enter进行手动导包) 四. 设置显示行号和方法间分隔符 五. 设置代码提 ...