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

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

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

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

跑一遍费用流。

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

转载于:https://www.cnblogs.com/Yinku/p/10624653.html

洛谷 - P2045 - 方格取数加强版 - 费用流相关推荐

  1. 网络流建模方法(四)—— 互不攻击问题 洛谷 P3353 骑士共存问题 (附 洛谷 P2774 方格取数问题)

    网络流建模方法(四)互不攻击问题,或者说是共存问题, 这类题目看起来有点像二分图匹配,这类题目我们就是建一个二分图然后跑最大流 还是先说题目洛谷P3353 题目描述 在一个 nn个方格的国际象棋棋盘上 ...

  2. 洛谷1004方格取数

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

  3. 洛谷 - P2774 方格取数问题(最小割-最大流+奇偶拆点)

    题目链接:点击查看 题目大意:给出一个n*m的棋盘,每个位置都有一个正整数,现在要从方格中取数,要求任意两个数在方格中的位置不相邻,求取出的数的最大和 题目分析:正难则反,在这个题目中正着建图比较难, ...

  4. 洛谷P1004方格取数

    var n,m,i,j,l,p,x,y,o:longint;fl:array[0..100] of array[0..100] of longint; //棋盘board:array[-2..51] ...

  5. 【网络流】解题报告: luogu P2045 方格取数加强版(k取方格数)(最大费用最大流)

    点边转化:把每个格子 (i,j) 拆成一个入点一个出点. 详解链接:[图论技巧]点边转化(拆点和拆边) 从每个入点向对应的出点连两条有向边:一条容量为 1 ,费用为格子 (i,j) 中的数: 另一条容 ...

  6. 洛谷 P1004 方格取数 【多线程DP/四维DP/】

    题目描述(https://www.luogu.org/problemnew/show/1004) 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0. ...

  7. 洛谷 P1004 方格取数 WD

    题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A0 0 0 0 0 0 0 00 0 13 0 0 6 0 0 ...

  8. P2045 方格取数加强版

    思路 简单的拆点 拆成入点和出点,对应点之间连一条cap=1,cost=x和一条cap=INF,cost=0的边,然后相邻点的出点和其他点的入点连边,然后S有k的流量,然后跑最大费用最大流就好了 代码 ...

  9. 【洛谷P1288】取数游戏II

    取数游戏II 题目链接 显然,由于一定有一个0,我们可以求出从初始点到0的链的长度 若有一条链长为奇数,则先手可以每次取完一条边上所有的数, 后手只能取另一条边的数,先手必胜: 反之若没有奇数链,后手 ...

最新文章

  1. ACMNO.8输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数。 输入 一行字符 输出 统计值 样例输入 aklsjflj123 sadf918u324 asdf91u32
  2. HDU1808(抽屉原理)
  3. 详解GPU的常见参数及其对显卡的重要性
  4. PHP的addslashes 函数详解
  5. [Unity Editor]10行代码搞定Hierarchy排序
  6. iOS 开发一定要尝试的 Texture(ASDK)
  7. 让人生成功的49个细节
  8. 系统背景描述_【计算机论文】管件加工管理系统和数据库的结构探析
  9. 在pycharm中使用conda虚拟环境(conda虚拟环境是已经创建好的),解决python安装包文件很费劲的问题
  10. Opencv之缺少api-ms-win-downlevel-shlwapi-l1-1-0
  11. Mysql跨表更新 多表update sql语句总结
  12. 笔记本电脑改光驱加装固态和内存条详细步骤教程
  13. 电脑联网了但是浏览器代理服务器出现了问题
  14. 清蒸野猪佩奇自带LastDance
  15. Java实现简易联网坦克对战小游戏
  16. UVA11584---区间DP
  17. javaweb操作数据库
  18. 理想运放传递函数的求解
  19. 零基础学习UI设计需要多长时间
  20. 当敦煌月牙泉遍布Wi-Fi:一个“新型智慧城市”打开方式是这样的

热门文章

  1. uva11728alternate task所有因子
  2. 从指定文件夹里COPY指定的一批文件列表(TXT文件)
  3. javascript控制validator
  4. 数据可视化之 星图
  5. 循环队列c语言的实现,循环队列的C语言实现
  6. idea 执行java maven,IDEA的run maven方式启动步骤详解
  7. 用java编写运行的小游戏_第一次用Java编写小游戏!
  8. java 添加联系人,java – 如何将联系人添加到组android
  9. Python知识点2——列表基础
  10. java win8 mac地址_Win8怎么查看MAC地址_Win8查看电脑MAC地址方法-192路由网