题目

还纠结了一下是费用流还是最小割

最终还是决定让最小割去死吧

我们的问题就是让一个点的点权只被计算一次

考虑拆点

  1. 将所有点拆成入点和出点,入点向出点连流量为\(1\)的边

  2. 每一个出点往下连能到达的点,向入点连费用为该点点权容量为\(0\)的边,向出点连费用为\(0\)容量为\(k-1\)的边

这样我们就能保证一个点的点权只被计算一次了

代码

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=5005;
const int inf=99999999;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct E{int v,nxt,w,f;}e[maxn*100];
const int dx[]={0,1};
const int dy[]={1,0};
std::queue<int> q;
int n,num=1,S,T,m,a[51][51],out[51][51],in[51][51];
int head[maxn],vis[maxn],d[maxn];
inline void C(int x,int y,int w,int f) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
e[num].w=w;e[num].f=f;
}
inline void add(int x,int y,int w,int f) {C(x,y,-1*w,f),C(y,x,w,0);}
inline int SPFA() {
for(re int i=S;i<=T;i++) vis[i]=0,d[i]=inf;
d[T]=0,q.push(T);
while(!q.empty()) {
int k=q.front();q.pop();vis[k]=0;
for(re int i=head[k];i;i=e[i].nxt)
if(e[i^1].f&&d[e[i].v]>d[k]+e[i^1].w) {
d[e[i].v]=d[k]+e[i^1].w;
if(!vis[e[i].v]) q.push(e[i].v),vis[e[i].v]=0;
}
}
return d[S]<inf;
}
int dfs(int x,int now) {
if(x==T||!now) return now;
int flow=0,ff;vis[x]=1;
for(re int i=head[x];i;i=e[i].nxt)
if(e[i].f&&!vis[e[i].v]&&d[e[i].v]==d[x]+e[i^1].w) {
ff=dfs(e[i].v,min(now,e[i].f));
if(ff<=0) continue;
flow+=ff,now-=ff,e[i].f-=ff,e[i^1].f+=ff;
if(!now) break;
}
return flow;
}
int main() {
n=read(),m=read();
for(re int i=1;i<=n;i++)
for(re int j=1;j<=n;j++) a[i][j]=read();
for(re int i=1;i<=n;i++)
for(re int j=1;j<=n;j++) in[i][j]=++T,out[i][j]=++T;
++T;
for(re int i=1;i<=n;i++)
for(re int j=1;j<=n;j++) add(in[i][j],out[i][j],0,1);
for(re int i=1;i<=n;i++)
for(re int j=1;j<=n;j++)
for(re int k=0;k<2;k++) {
int x=i+dx[k],y=j+dy[k];
if(x<1||y<1||x>n||y>n) continue;
add(out[i][j],in[x][y],a[x][y],1);
add(out[i][j],out[x][y],0,inf);
}
int ans=0;
add(S,in[1][1],a[1][1],1);add(S,out[1][1],0,m-1);
add(out[n][n],T,0,m);
while(SPFA()) {
vis[T]=1;
while(vis[T]) {
for(re int i=S;i<=T;i++) vis[i]=0;
ans-=dfs(S,inf)*d[S];
}
}
printf("%d\n",ans);
return 0;
}

【LGP2045】方格取数加强版的更多相关文章

  1. P2045 方格取数加强版

    P2045 方格取数加强版 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格 ...

  2. [luogu_P2045]方格取数加强版

    [luogu_P2045]方格取数加强版 试题描述 给出一个 \(n \times n\) 的矩阵,每一格有一个非负整数 \(A_{i,j},(A_{i,j} \le 1000)\) 现在从 \((1 ...

  3. Luogu2045 方格取数加强版

    题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变 ...

  4. Luogu2045 方格取数加强版(K取方格数) 费用流

    题目传送门 题意:给出一个$N \times N$的方格,每个格子中有一个数字.你可以取$K$次数,每次取数从左上角的方格开始,每一次只能向右或向下走一格,走到右下角结束,沿路的方格中的数字将会被取出 ...

  5. 洛谷 P2045 方格取数加强版【费用流】

        题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...

  6. P2045 方格取数加强版 最大费用最大流

    $ \color{#0066ff}{ 题目描述 }$ 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每 ...

  7. poj 3422 洛谷P2045 K取方格数(方格取数加强版)

    Description: 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来 ...

  8. [洛谷P2045]方格取数加强版

    题目大意:有一个n*n的矩阵,每个格子有一个非负整数,规定一个人从(1,1)开始,只能往右或下走,走到(n,n)为止,并把沿途的数取走,取走后数变为0.这个人共取n次,求取得的数的最大总和. 解题思路 ...

  9. 洛谷 - P2045 - 方格取数加强版 - 费用流

    原来这种题的解法是费用流. 从一个方格的左上走到右下,最多走k次,每个数最多拿走一次. 每次走动的流量设为1,起始点拆点成限制流量k. 每个点拆成两条路,一条路限制流量1,费用为价值相反数.另一条路无 ...

随机推荐

  1. Hadoop worldcount

    以前的公司和现在的公司,都用到了hadoop和hdfs.一直没入门,今天照着官网写了一个hadoop worldcount demo 1. hadoop是一个框架,什么是框架,spring是一个框架. ...

  2. C# 进程通信-命名管道

    之前看wcf服务的时候看到wcf有支持管道通信协议,之前不知道,最近刚好有用到这个,这里写个简单实例 .net有已经封装好的pip通信的对象NamedPipeServerStream 和NamedPi ...

  3. js事件队列

    前面跟网友讨论到了JS的事件队列 ,对这个有了一些理解,事件队列我认为就是把一些不按顺序执行的事件放到队列里面,然后按照自己制定的顺序去执行,那么什么情况下会用到这个呢?我首先想到的是动画,动画是会执 ...

  4. slice()方法 和splice 方法的区别

    定义 splice() 方法 用于插入.删除或替换数组的元素. slice() 方法 可提取字符串的某个部分,并以新的字符串返回被提取的部分. 更多的可查看: http://www.cnblogs.c ...

  5. How to safely downgrade or remove glibc with yum and rpm

    Environment Red Hat Enterprise Linux 5 Red Hat Enterprise Linux 6 glibc, glibc-common, glibc-devel, ...

  6. 封装网络请求并在wxml调用

    https://blog.csdn.net/qq_35713752/article/details/78109084 // url:网络请求的url method:网络请求方式 data:请求参数 m ...

  7. 深入理解HashMap和concurrentHashMap

    原文链接:https://segmentfault.com/a/1190000015726870 前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇 ...

  8. jquery使页面滚动到底部

    function scrollToEnd(){//滚动到底部 var h = $(document).height()-$(window).height(); $(document).scrollTo ...

  9. webpack笔记一 起步

    webpack笔记一 起步 安装 对于大多数项目,我们建议本地安装(--save-dev).这可以在引入突破式变更(breaking change)版本时,更容易分别升级项目. 起步 初始化项目 mk ...

  10. 3 Dockerfile指令详解-FROM&MAINTAINER&RUN

    1.FROM指令 FROM centos #指定centos为基础镜像 2.MAINTAINER 指令 MAINTAINER @QQ.COM #指定维护人等信息,方便维护 3.RUN  命令  #新建 ...