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 ...
随机推荐
- linux导出安装包
linux导出安装包 1 背景 部署企业内网环境,主机无法连通外网.不能直接使用yum install安装程序.针对此种情况有如下两个安装办法 源码安装(需要编译环境,安装复杂,容易出错,不推荐) 使 ...
- Java获取电脑盘符(最后一个盘符)
//遍历获得所有盘符 File[] roots = File.listRoots(); for (int i =0; i < roots.length; i++) { System.out.pr ...
- 2024-05-04:用go语言,给定一个起始索引为0的字符串s和一个整数k。 要进行分割操作,直到字符串s为空: 选择s的最长前缀,该前缀最多包含k个不同字符; 删除该前缀,递增分割计数。如果有剩余
2024-05-04:用go语言,给定一个起始索引为0的字符串s和一个整数k. 要进行分割操作,直到字符串s为空: 选择s的最长前缀,该前缀最多包含k个不同字符: 删除该前缀,递增分割计数.如果有剩余 ...
- fork后更新仓库代码
目录 fork后更新仓库代码 场景: 模型 操作方法如下: 方法一.从github上进行操作然后更新 如何在 Github 网页端同步更新? 方法二.通过命令行fetch拉取原仓库更新 fork后更新 ...
- 鸿蒙HarmonyOS实战-ArkUI事件(手势方法)
一.手势方法 应用程序的手势操作是指在移动设备上使用手指或手势进行与应用程序交互的方式.手势操作可以包括点击.滑动.双击.捏合等动作,用于实现不同的功能和操作. HarmonyOS中常见的手势操作及其 ...
- DNS(2) -- bind服务介绍及配置文件语法格式
目录 1. bind服务 1.1 bind概述 1.2 bind程序包结构 1.3 bind配置文件详解 1.3.1 bind配置文件 1.3.1.1 bind主配置文件 1.3.1.2 bind区域 ...
- 密码学—Vigenere破解Python程序
文章目录 概要 预备知识点学习 整体流程 技术名词解释 技术细节 小结 代码 概要 破解Vigenere需要Kasiski测试法与重合指数法的理论基础 具体知识点细节看下面这两篇文章 预备知识点学习 ...
- .net core 微信支付-微信小程序支付(服务端C#代码)
前言 前段时间研究了下微信支付-小程序支付的功能.但微信支付文档中关于.net C#的语言的sdk没有,只有java go 和php版本的,当然社区也有很多已经集成好的微信支付.net core sd ...
- 定了!航天科技AIRIOT 物联网平台新品发布会,6月6日北京见!
AIRIOT新品发布会预告 航天科技定档6月6日举办AIRIOT新品发布会,诚邀大家共同见证4.0版本的创新与赋能! 活动地点:北京雍和航星科技园. 现场参会请通过下方长图二维码进行报名! 亦可预约直 ...
- snmpwalk命令详解
snmp安装 yum -y install net-snmp-libs net-snmp net-snmp-utils 系统镜像里面就有这些包.可yum安装 snmpwalk集合 snmpwalk + ...