Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)

Description

在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。对于给定的方格棋盘,按照取数要求编程找出总和最大的数。

Input

第 1 行有 2 个正整数 m 和 n,分别表示棋盘的行数和列数。接下来的 m 行,每行有 n 个正整数,表示棋盘方格中的数。

Output

程序运行结束时,将取数的最大总和输出

Sample Input

3 3

1 2 3

3 2 3

2 3 1

Sample Output

11

Http

Libre:https://loj.ac/problem/6007

Luogu:https://www.luogu.org/problem/show?pid=2774

Source

网络流,最大流

解决思路

总觉的这道题能想到用网络流解很玄学

网络流的另外一种模型:点覆盖模型,就是有诸如两个只能选一个的限制这类,没有做过的话根本想不到。

我们把网格黑白染色,让黑格周围都是白格,白格同理,简单点来说对于格子(i,j),若i%2==j%2则黑色,否则白色。

另外建立一个源点一个汇点。对于每一个黑色的格子,从源点连一条容量为格子上的数的边,并且向周围的所有相邻白格子连一条容量为无穷大的边。对于每一个白格子,从白格子连一条容量位格子上的数的边到汇点。

同时,统计所有格子上的数之和 记为sum。求出最大流flow,则答案就是flow-sum。

这种解法的原理是基于最小割最大流,由于笔者知识水平不高,暂且不知道如何证明。但可以通过画图手动模拟的方式基本上可以认识到其正确性,即通过巧妙的方式割去其中部分边点,使得剩下的最大(笔者也只能理解到这里了)

另:这里使用Dinic实现最大流,具体可以移步我的这篇文章

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; #define pos(x,y) (x-1)*n+y const int maxN=40;
const int inf=2147483647; class Edge
{
public:
int u,v,flow;
}; int n,m;
int cnt=-1;
int Mat[maxN][maxN];
int Head[maxN*maxN];
int Next[maxN*maxN*maxN*maxN];
Edge E[maxN*maxN*maxN*maxN];
int depth[maxN*maxN];
int cur[maxN*maxN];
int Q[maxN*maxN*maxN]; void Add_Edge(int u,int v,int flow);
bool bfs();
int dfs(int u,int flow); int main()
{
memset(Head,-1,sizeof(Head));
int sum=0;
scanf("%d%d",&m,&n);
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
{
int num;
scanf("%d",&num);
sum+=num;//sum统计所有格子的权之和
if (i%2==j%2)//若为黑格子
{
Add_Edge(0,pos(i,j),num);//连接源点
if (i!=1)//分别连接四周的白格子,注意判断存在与否
Add_Edge(pos(i,j),pos(i-1,j),inf);
if (i!=m)
Add_Edge(pos(i,j),pos(i+1,j),inf);
if (j!=1)
Add_Edge(pos(i,j),pos(i,j-1),inf);
if (j!=n)
Add_Edge(pos(i,j),pos(i,j+1),inf);
}
else
Add_Edge(pos(i,j),n*m+1,num);//若为白格子,则只连接汇点
}
int Ans=0;
while (bfs())//求解最大流
{
memcpy(cur,Head,sizeof(cur));
while (int di=dfs(0,inf))
Ans+=di;
}
cout<<sum-Ans<<endl;
return 0;
} void Add_Edge(int u,int v,int flow)
{
cnt++;
Next[cnt]=Head[u];
Head[u]=cnt;
E[cnt].u=u;
E[cnt].v=v;
E[cnt].flow=flow; cnt++;
Next[cnt]=Head[v];
Head[v]=cnt;
E[cnt].u=v;
E[cnt].v=u;
E[cnt].flow=0;
} bool bfs()
{
memset(depth,-1,sizeof(depth));
int h=1,t=0;
Q[1]=0;
depth[0]=1;
do
{
t++;
int u=Q[t];
for (int i=Head[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((E[i].flow>0)&&(depth[v]==-1))
{
h++;
Q[h]=v;
depth[v]=depth[u]+1;
}
}
}
while (t!=h);
if (depth[n*m+1]==-1)
return 0;
return 1;
} int dfs(int u,int flow)
{
if (u==n*m+1)
return flow;
for (int i=Head[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((E[i].flow>0)&&(depth[v]==depth[u]+1))
{
int di=dfs(v,min(flow,E[i].flow));
if (di>0)
{
E[i].flow-=di;
E[i^1].flow+=di;
return di;
}
}
}
return 0;
}

Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)的更多相关文章

  1. LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

    #6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  2. Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)

    Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...

  3. Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)

    Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...

  4. Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)

    Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...

  5. Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)

    Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...

  6. Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)

    Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算) Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放 ...

  7. Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)

    Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流) Description 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. ...

  8. Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)

    Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流) Description 问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同 ...

  9. Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)

    Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流) Description 问题描述: 给定正整数序列x1,...,xn . (1 ...

随机推荐

  1. C# ConcurrentBag的实现原理

    目录 一.前言 二.ConcurrentBag类 三. ConcurrentBag线程安全实现原理 1. ConcurrentBag的私有字段 2. 用于数据存储的TrehadLocalList类 3 ...

  2. 同步、异步、回调执行顺序之经典闭包setTimeout分析

    聊聊同步.异步和回调 同步,异步,回调,我们傻傻分不清楚, 有一天,你找到公司刚来的程序员小T,跟他说:“我们要加个需求,你放下手里的事情优先支持,我会一直等你做完再离开”.小T微笑着答应了,眼角却滑 ...

  3. SVN基础操作

    SVN基础操作 安装 #大多数Linux版本自带svn svn --version #如果没有安装可用yum安装 yum install subversion 生命周期 创建版本库 检出 更新 执行变 ...

  4. (转)Unity内建图标列表

    用法 Gizmos.DrawIcon(transform.position, "PointLight Gizmo"); UnityEditor.EditorGUIUtility.F ...

  5. React笔记-事件分发

    事件分发 之前讲述了事件如何绑定在document上,那么具体事件触发的时候是如何分发到具体的监听者呢?我们接着上次注册的事件代理看.当我点击update counter按钮时,触发注册的click事 ...

  6. 《Pro SQL Server Internals, 2nd edition》的CHAPTER 2 Tables and Indexes中的Clustered Indexes一节(翻译)

    <Pro SQL Server Internals> 作者: Dmitri Korotkevitch 出版社: Apress出版年: 2016-12-29页数: 804定价: USD 59 ...

  7. 学习笔记 | CDQ分治

    目录 前言 啥是CDQ啊(它的基本思想) 例题 后记 参考博文 前言 博主太菜了 学习快一年的OI了 好像没有什么会的算法 更寒碜的是 学一样还不精一样TAT 如有什么错误请各位路过的大佬指出啊感谢! ...

  8. 理解以太坊的Layer 2扩容解决方案:状态通道(State Channels)、Plasma 和 Truebit

    -宾夕法尼亚州的尼科尔森大桥建设照片(图源).罗马人的工程原理扩展至新的应用 对于以太坊来说,2018年是专注底层架构之年.今年很多早期参与者会测试网络极限,并且重新关注以太坊的扩容技术. 以太坊仍然 ...

  9. EOS开发基础之一:源代码下载与开发环境搭建

    区块链最近挺火的,我又是个非常缺钱的人,所以紧跟了潮流一头扎进区块链的研究中. 这EOS项目是目前比较火的一个项目,相信很多朋友拿到这份EOS的源代码后都会一脸懵逼,因为……这代码写得太高级了,老纸看 ...

  10. SCRUM 12.17

    今天,我们的用户统计功能终于上线了!! 大家辛苦工作了许久.我们测试的用户统计功能效果模拟如下 还有一些好消息,比如,我们的应用在小米平台收到了崩溃的反馈报告. 这说明我们留下的一些BUG暴露了出来, ...