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. 20155229《网络对抗技术》Exp6:信息收集与漏洞扫描

    实验内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测.具体服务的查点 (4)漏洞扫描:会扫,会看报告,会查漏洞说明,会修补 ...

  2. 20155307《网络对抗》MSF基础应用

    实验过程 实验系统 所需设备: 靶机1:Windows XP Professional SP2 ,IP地址:192.168.1.128 靶机2:Windows XP Professional SP3 ...

  3. python 回溯法 子集树模板 系列 —— 10、m着色问题

    问题 图的m-着色判定问题 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色,是否有一种着色法使G中任意相邻的2个顶点着不同颜色? 图的m-着色优化问题 若一个图最少 ...

  4. Hadoop开发第6期---HDFS的shell操作

    一.HDFS的shell命令简介 我们都知道HDFS 是存取数据的分布式文件系统,那么对HDFS 的操作,就是文件系统的基本操作,比如文件的创建.修改.删除.修改权限等,文件夹的创建.删除.重命名等. ...

  5. Linux 设置core dump

    Linux 设置core dump

  6. angular-ui-router速学

    Demo1 初始化 <html ng-app="app"> <head> <style>.active { color: red; font-w ...

  7. exchange 2010 的两个错误

    最近公司要搭建邮件服务器 过程中 碰到两个问题,记录下来. 引以为戒 . 1,登陆界面能出来 但是无论输入什么都显示 乱码.问题原因 身份验证有问题. 如图所示:  改成这个,然后 重启 iis 就可 ...

  8. Docker_容器化jenkins

    Docker部署接口自动化持续集成环境第二步,容器化一个Jenkins! 接上文:Docker_容器化gitlab 1:pull一个jenkins镜像 docker pull jenkins 2:查看 ...

  9. linux 常用命令-tar(压缩、解压)

    linux中通过tar命令来压缩解压文件,常用命令如下 主选项(主选项是必须要有的,作用是告诉这次操作的主要目的): 1)c: (create)创建压缩包或者打包 2)x:(extract)拆包 3) ...

  10. 『编程题全队』Alpha 阶段冲刺博客Day7

    1.每日站立式会议 1.会议照片 2.昨天已完成的工作统计 孙志威: 1.添加了网络通信管理类 2.稍微修改了燃尽图模块ChartWidget 3.在主窗口中添加了用户信息框 4.重构了项目中的文件结 ...