原来这种题的解法是费用流。

从一个方格的左上走到右下,最多走k次,每个数最多拿走一次。

每次走动的流量设为1,起始点拆点成限制流量k。

每个点拆成两条路,一条路限制流量1,费用为价值相反数。另一条路无限流量。

跑一遍费用流。

#include<bits/stdc++.h>
using namespace std; const int MAXN=+;
const int MAXM=;
const int INF=0x3f3f3f3f;
struct Edge{
int to,next,cap,flow,cost;
}edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN]; int n;
void init(){
tol=;
memset(head,-,sizeof(head));
} void addedge(int u,int v,int cap,int cost){
edge[tol].to=v;
edge[tol].cap=cap;
edge[tol].cost=cost;
edge[tol].flow=;
edge[tol].next=head[u];
head[u]=tol++; edge[tol].to=u;
edge[tol].cap=;
edge[tol].cost=-cost;
edge[tol].flow=;
edge[tol].next=head[v];
head[v]=tol++;
} bool spfa(int s,int t){
queue<int> q;
memset(dis,INF,sizeof(dis));
memset(vis,false,sizeof(vis));
memset(pre,-,sizeof(pre)); dis[s]=;
vis[s]=true;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=true;
q.push(v);
}
}
}
}
if(pre[t]==-)
return false;
else
return true;
} int minCostMaxFlow(int s,int t,int &cost){
int flow=;
cost=;
while(spfa(s,t)){
int Min=INF;
for(int i=pre[t];i!=-;i=pre[edge[i^].to]){
if(Min>edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
}
for(int i=pre[t];i!=-;i=pre[edge[i^].to]){
edge[i].flow+=Min;
edge[i^].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
} void show(int s){
bool vis[];
queue<int> q;
vis[s]=;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
cout<<"u="<<u<<endl;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(vis[v]==){
vis[v]=;
q.push(v);
}
}
}
cout<<endl;
} /* EK end */ int a[][]; int k; inline int getid(int i,int j,int isout){
return (i-)*n+j+isout*(n*n);
} int main(){
init();
scanf("%d%d",&n,&k); int si=*n*n+,so=*n*n+;
addedge(si,so,k,);//最多走k次
int t=*n*n+; for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
int c;
scanf("%d",&c);
addedge(getid(i,j,),getid(i,j,),,-c);
//拿走它,获得价值,费用是相反数
addedge(getid(i,j,),getid(i,j,),INF,);
//不拿就不拿呗
}
} for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(i+<=n)
addedge(getid(i,j,),getid(i+,j,),INF,);
if(j+<=n)
addedge(getid(i,j,),getid(i,j+,),INF,);
}
} addedge(so,getid(,,),INF,);
addedge(getid(n,n,),t,INF,); //show(si); int cost=;
int flow=minCostMaxFlow(si,t,cost);
printf("%d\n",-cost); }

洛谷 - P2045 - 方格取数加强版 - 费用流的更多相关文章

  1. 洛谷P2045 方格取数加强版(费用流)

    题意 题目链接 Sol 这题能想到费用流就不难做了 从S向(1, 1)连费用为0,流量为K的边 从(n, n)向T连费用为0,流量为K的边 对于每个点我们可以拆点限流,同时为了保证每个点只被经过一次, ...

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

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

  3. 洛谷P2045 方格取数加强版 最小费用流

    Code: #include<cstdio> #include<cstring> #include<algorithm> #include<queue> ...

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

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

  5. LG2045 方格取数加强版 费用流

    问题描述 LG2045 题解 费用流. 套路拆点,把\((i,j)\)拆为两个点,在这两个点之间连边:一条边流量为\(1\),费用为\(a_{i,j}\),另一条边为流量为\(INF\),费用为\(0 ...

  6. P2045 方格取数加强版

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

  7. 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏

    P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...

  8. 洛谷 P2774 方格取数问题 解题报告

    P2774 方格取数问题 题目背景 none! 题目描述 在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...

  9. 洛谷 P1004 方格取数 题解

    P1004 方格取数 题目描述 设有 \(N \times N\) 的方格图 \((N \le 9)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字\(0\).如下图所示(见样例): ...

随机推荐

  1. BUPT复试专题—List(2015)

    题目描述 在该LIST上实现3种操作 1.append x在该LIST末尾添加x,x是32位整数 2.pop删除该LIST末尾的数 3.find i寻找第i个数,若i为负数表示寻找倒数第i个数,例如i ...

  2. Unity3d插件]EasyTouch简单使用方法

    EasyTouch使用 EasyTouch 文件夹[-] 一.效果图 二.操作步骤 1.官方文档上的步骤 2.翻译一下以上的步骤 3.依据官方的这些提示.自己来做一个属于自己的人物遥感控制 对于移动平 ...

  3. ubuntu如何修改root密码

    安装完Ubuntu后忽然意识到没有设置root密码,不知道密码自然就无法进入根用户下.到网上搜了一下,原来是这麽回事.Ubuntu的默认root密码是随机的,即每次开机都有一个新的root密码.我们可 ...

  4. (转) Universal-Image-Loader使用大全(史上最屌)

    转载自http://blog.csdn.net/zenjj11/article/details/38728481 项目介绍: Android上最让人头疼的莫过于从网络获取图片.显示.回收,不论什么一个 ...

  5. openwrt gstreamer实例学习笔记(七. gstreamer 缓冲区(Buffers)和事件(Events))

    1)概述 管道的数据流由一组缓冲区和事件组成,缓冲区包括实际的管道数据,事件包括控制信息,如寻找信息和流的终止信号.所有这些数据流在运行的时候自动的流过管道. 2) 缓冲区(Buffers) 缓冲区包 ...

  6. 应用require.js进行javascript模块化编程小试一例

    长久以来都渴望应用javascript的模块化编程.今日紧迫更甚,岁月蹉跎,已经不能再等了. 拜读阮一峰的有关文章已经好几遍,文章写得真好,简洁流畅,头头是道,自觉有点明白了.但经验告诉我们,一定要亲 ...

  7. apache benchmark

    1 ab是什么 是一个web高并发测试工具,可以发送get.put.post请求. 2 ab -n和-c共存 -c是concurrency的缩写,即同一时间发送多个请求. -n是指本次总共发送多少个请 ...

  8. python dictionary的遍历

    d = {'x':1, 'y':3, 'z':2} for k in d:    print d[k] 直接遍历k in d的话,遍历的是dictionary的keys. 2 字典的键可以是任何不可变 ...

  9. 编译spark源码 Maven 、SBT 2种方式编译

    由于实际环境较为复杂,从Spark官方下载二进制安装包可能不具有相关功能或不支持指定的软件版本,这就需要我们根据实际情况编译Spark源代码,生成所需要的部署包. Spark可以通过Maven和SBT ...

  10. JAVA反射改动常量,以及其局限

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/barryhappy/article/details/24442953 问题,以及一个解决方式 今天公 ...