【Luogu】P2045方格取数加强版(最小费用最大流)
通过这题我学会了引诱算法的行为,就是你通过适当的状态设计,引诱算法按照你想要它做的去行动,进而达到解题的目的。
最小费用最大流,首先将点拆点,入点和出点连一条费用=-权值,容量=1的边,再连费用=0,容量=INF的边,跑最小费用最大流即可。
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#define maxn 10000
#define maxm 500000
using namespace std; inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} int count(int i){ return i&?i+:i-; }
int calc(int i,int j,int n){ return (i-)*n+j; } struct Edge{
int from,next,to,val,flow,dis;
}edge[maxm];
int head[maxn],num;
inline void addedge(int from,int to,int val,int dis){
edge[++num]=(Edge){from,head[from],to,val,,dis};
head[from]=num;
}
inline void add(int from,int to,int val,int dis){
addedge(from,to,val,dis);
addedge(to,from,,-dis);
} bool vis[maxn];
int dst[maxn];
int flow[maxn];
int pre[maxn];
int Start,End; int spfa(){
memset(vis,,sizeof(vis));
memset(dst,/,sizeof(dst));
queue<int>q; q.push(Start); dst[Start]=; flow[Start]=0x7fffffff;
while(!q.empty()){
int from=q.front(); q.pop(); vis[from]=;
for(int i=head[from];i;i=edge[i].next){
int to=edge[i].to;
if(dst[to]<=dst[from]+edge[i].dis||edge[i].val<=edge[i].flow) continue;
pre[to]=i;
dst[to]=dst[from]+edge[i].dis;
//printf("%d %d %d\n",from,to,dst[to]);
flow[to]=min(flow[from],edge[i].val-edge[i].flow);
if(vis[to]) continue;
vis[to]=; q.push(to);
}
}
if(dst[End]==dst[End+]) return ;
int now=End;
while(now!=Start){
int ret=pre[now];
edge[ret].flow+=flow[End]; edge[count(ret)].flow-=flow[End];
now=edge[ret].from;
}
return dst[End];
} int q[maxn][maxn]; int main(){
int n=read(),k=read(); End=maxn-;
for(int i=;i<=n;++i)
for(int j=;j<=n;++j){
q[i][j]=read();
add(calc(i,j,n),calc(i,j,n)+n*n,,-q[i][j]);
add(calc(i,j,n),calc(i,j,n)+n*n,0x7fffffff,);
}
for(int i=;i<=n;++i)
for(int j=;j<=n;++j){
if(i^n) add(calc(i,j,n)+n*n,calc(i+,j,n),0x7fffffff,);
if(j^n) add(calc(i,j,n)+n*n,calc(i,j+,n),0x7fffffff,);
}
add(Start,calc(,,n),0x7fffffff,);
add(calc(n,n,n)+n*n,End,0x7fffffff,);
int ans=;
for(int i=;i<=k;++i) ans+=-spfa();
printf("%d",ans);
}
【Luogu】P2045方格取数加强版(最小费用最大流)的更多相关文章
- P2045 方格取数加强版 最大费用最大流
$ \color{#0066ff}{ 题目描述 }$ 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每 ...
- 洛谷 P2045 方格取数加强版【费用流】
题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...
- P2045 方格取数加强版
P2045 方格取数加强版 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格 ...
- 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的边 对于每个点我们可以拆点限流,同时为了保证每个点只被经过一次, ...
- [洛谷P2045]方格取数加强版
题目大意:有一个n*n的矩阵,每个格子有一个非负整数,规定一个人从(1,1)开始,只能往右或下走,走到(n,n)为止,并把沿途的数取走,取走后数变为0.这个人共取n次,求取得的数的最大总和. 解题思路 ...
- [CodeVs1227]方格取数2(最大费用最大流)
网络流24题的坑还没填完,真的要TJ? 题目大意:一个n*n的矩阵,每格有点权,从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走 ...
- 洛谷 - P2045 - 方格取数加强版 - 费用流
原来这种题的解法是费用流. 从一个方格的左上走到右下,最多走k次,每个数最多拿走一次. 每次走动的流量设为1,起始点拆点成限制流量k. 每个点拆成两条路,一条路限制流量1,费用为价值相反数.另一条路无 ...
- 洛谷P2045 方格取数加强版 最小费用流
Code: #include<cstdio> #include<cstring> #include<algorithm> #include<queue> ...
随机推荐
- JAVA多线程编程——JAVA内存模型
一.何为“内存模型” 内存模型描述了程序中各个变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量这样的底层细节,对象最终是存储在内存里面的,但是编译器 ...
- 通过WMIC导出系统日志
查看日志类型 wmic nteventlog get filename C:\>wmic nteventlog get filename FileName appevent secevent s ...
- C#之winform实现文件拖拽功能【转】
将一个文件拖拽到窗体的某个控件时,将该控件的路径显示在该控件上,只要拿到了路径自然可以读取文件中的内容了 将一个控件的属性AllowDrop设置为true,然后添加DragDrop.DragEnter ...
- Spring boot 配置异步处理执行器
示例如下: 1. 新建Maven 项目 async-executor 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...
- Java中的ArrayList类和LinkedList
集合的体系: ----------| Collection 单列集合的根接口----------------| List 如果实现了List接口的集合类,具备的特点: 有序,可重复.--------- ...
- 使用的是html5的canvas将文字转换成图片
当前功能的运用场景是:用户需要传文件给他人,在用户选择文件之后需要显示一个文件图标和所选文件的名称. 当前代码部分是摘自网上,但是已经忘记在什么地方获取的,如有侵权联系小弟后自当删除. 注意:必须在h ...
- cocos2dx通过ndk编译c++库
ndk编译c++库,然后通过jni调用实现重要代码封装,是安卓应用中最常用的技术,一方面可以将重要的代码实现隐藏,防止泄漏,也可以提高打包速度. ndk里面的sample文件夹中有很多实用的例子,其中 ...
- unity3d sqlite数据库的读写方法
首先,我们要从unity的安装路径中复制mono.data.sqlite.dll和sqlite3.dll两个动态链接库到untiy的plugins目录下,如下图所示: 使用navicat for sq ...
- runtime实践之Method Swizzling
利用 Objective-C 的 Runtime 特性,我们可以给语言做扩展,帮助解决项目开发中的一些设计和技术问题.这一篇,我们来探索一些利用 Objective-C Runtime 的黑色技巧.这 ...
- VueJS坎坷之路111---_self.$scopedSlots.default is not a function
VueJs + Element 话不多说,直接贴错: _self.$scopedSlots.default is not a function <el-table stripe border r ...