洛谷 P2774 方格取数问题 解题报告
P2774 方格取数问题
题目背景
none!
题目描述
在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。对于给定的方格棋盘,按照取数要求编程找出总和最大的数。
输入输出格式
输入格式:
第 \(1\) 行有 \(2\) 个正整数 \(m\) 和 \(n\),分别表示棋盘的行数和列数。接下来的 \(m\) 行,每行有 \(n\) 个正整数,表示棋盘方格中的数。
输出格式:
程序运行结束时,将取数的最大总和输出
说明
\(n,m\le 100\)
积累一下思维方式
棋盘不妨先进行黑白染色,然后可以得到一个二分图。
考虑我们需要把点集划分成两份,两份之间没有边连接,可以联想到最小割是做这个的。
最小割割的是边,想办法把点权搞到边上,因为我们本来就是二分图,所以两边源汇直接连点权的容量,图两边连inf,表示割不掉。其余边割掉代表割的是点,然后就把两个图搞不连通了。
Code:
#include <cstdio>
#include <cstring>
const int N=1e4+10;
const int inf=0x3f3f3f3f;
int min(int x,int y){return x<y?x:y;}
int head[N],to[N<<4],Next[N<<4],edge[N<<4],cnt=1;
void add(int u,int v,int w)
{
to[++cnt]=v,edge[cnt]=w,Next[cnt]=head[u],head[u]=cnt;
to[++cnt]=u,edge[cnt]=0,Next[cnt]=head[v],head[v]=cnt;
}
int q[N],l,r,dep[N],n,m,s,t,sum;
bool bfs()
{
memset(dep,0,sizeof dep);
dep[q[l=r=1]=s]=1;
while(l<=r)
{
int now=q[l++];
for(int v,i=head[now];i;i=Next[i])
if(!dep[v=to[i]]&&edge[i])
{
dep[v]=dep[now]+1;
if((q[++r]=v)==t) return true;
}
}
return false;
}
int dfs(int now,int flow)
{
if(now==t) return flow;
int res=flow,bee;
for(int v,i=head[now];i&&res;i=Next[i])
if(dep[v=to[i]]==dep[now]+1&&edge[i])
{
bee=dfs(v,min(res,edge[i]));
if(!bee) dep[v]=0;
edge[i]-=bee,edge[i^1]+=bee;
res-=bee;
}
return flow-res;
}
const int dx[5]={0,-1,0,1,0};
const int dy[5]={0,0,1,0,-1};
int main()
{
scanf("%d%d",&n,&m);
s=n*m+1,t=s+1;
for(int x,i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&x);
sum+=x;
int id=(i-1)*m+j;
if(i+j&1)
{
add(s,id,x);
for(int k=1;k<=4;k++)
{
int di=i+dx[k],dj=j+dy[k];
if(di&&dj&&di<=n&&dj<=m)
add(id,(di-1)*m+dj,inf);
}
}
else add(id,t,x);
}
int flow,maxflow=0;
while(bfs())
if(flow=dfs(s,inf)) maxflow+=flow;
printf("%d\n",sum-maxflow);
return 0;
}
2019.1.16
洛谷 P2774 方格取数问题 解题报告的更多相关文章
- 洛谷 - P2774 - 方格取数问题 - 二分图最大独立点集 - 最小割
https://www.luogu.org/problemnew/show/P2774 把两个相邻的节点连边,这些边就是要方便最小割割断其他边存在的,容量无穷. 这种类似的问题的话,把二分图的一部分( ...
- [洛谷P2774]方格取数问题
题目大意:给你一个$n\times m$的方格,要求你从中选择一些数,其中没有相邻两个数,使得最后和最大 题解:网络流,最小割,发现相邻的两个点不可以同时选择,进行黑白染色,原点向黑点连一条容量为点权 ...
- 洛谷P2774 方格取数问题(最小割)
传送门 考虑一下,答案就是全局和减去舍弃和 不难发现,如果我们按行数+列数的奇偶性分为两类,那么每一类中的数必然互不相邻 那么我们把原图的点分为黑点和白点两类,原地向白点连边,黑点向汇点连边,容量为点 ...
- 洛谷P2774 方格取数问题(最小割)
题意 $n \times m$的矩阵,不能取相邻的元素,问最大能取多少 Sol 首先补集转化一下:最大权值 = sum - 使图不连通的最小权值 进行黑白染色 从S向黑点连权值为点权的边 从白点向T连 ...
- 洛谷 [P2774] 方格取数问题
二分图最大点权独立集 通过题目描述我们可以很明显的看出要通过二分图建模,二分图求最大独立点集很容易,就是建立二分图求n-最小割,然而这里加入了权值,而且权值是在点上的,那么我们对于每个点连一条到源点或 ...
- 洛谷 P2774 方格取数问题【最小割】
因为都是正整数,所以当然取得越多越好.先把所有点权加起来,黑白染色后,s向所有黑点连流量为点权的边,所有白点向t连流量为点权的边,然后黑点向相邻的四个白点连流量为inf的边,表示不可割,这样一来,对于 ...
- 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏
P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...
- 洛谷 P1004 方格取数 题解
P1004 方格取数 题目描述 设有 \(N \times N\) 的方格图 \((N \le 9)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字\(0\).如下图所示(见样例): ...
- 洛谷 P1004 方格取数 【多进程dp】
题目链接:https://www.luogu.org/problemnew/show/P1004 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 ...
随机推荐
- 【转】浅谈JavaScript中forEach与each
forEach是ES5中操作数组的一种方法,主要功能是遍历数组,例如: var arr = [1,2,3,4]; arr.forEach(alert); 等价于: var arr = [1, 2, 3 ...
- C# 枚举基本用法及扩展方法
没什么好说的,都是些基础! 代码如下: using System; using System.Collections.Generic; using System.ComponentModel; usi ...
- MySQL高可用方案MHA在线切换的步骤及原理
在日常工作中,会碰到如下的场景,如mysql数据库升级,主服务器硬件升级等,这个时候就需要将写操作切换到另外一台服务器上,那么如何进行在线切换呢?同时,要求切换过程短,对业务的影响比较小. MHA就提 ...
- Redis数据"丢失"讨论及规避和解决的几点总结
Redis大部分应用场景是纯缓存服务,请求后端有Primary Storage的组件,如MySQL,HBase;请求Redis的键未命中,会从primary Storage中获取数据返回,同时更新Re ...
- Vue 回顾之指令(关于input自动聚焦的问题)
用了Vue也一年多了,虽然对大部分内容都比较熟悉,但有些用法可能会起到意想不到的作用. 今天在做一个关于抽奖的需求,要求是每次点击编辑按钮显示编辑框,要求自动聚焦. 一开始想到了autofocus属性 ...
- java注解的简单介绍
什么是注解 1.注解就是Annontation,Annontation是Java5开始引入的新特征,中文名称叫做注解,它提供了一种安全的类似注释的机制,可以起到减少配置的成果,给程序起到辅助性的作用 ...
- 机器学习算法(KNN)
KNN简介 KNN(k-NearestNeighbor)算法的思想总结一下:就是在数据和标签已知的情况下,输入测试数据,将测试数据的特征与训练集中对应的特征进行相互比较,找到训练集中与之最为相似的前K ...
- DockerHub使用简介
常用的Docker镜像文件都有,就不用自己费劲的一点点配置了,这才是Docker的真正目的.就像Ghost里边含office,直接还原,不用一台台机器安装呢,省时省力,与高效工作的理念相契合. 至于, ...
- OA实例
let express = require('express'); let consolidate = require('consolidate'); let bodyParser = require ...
- Linux标准输入、输出和错误和文件重定向 专题
当我们在shell中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件.由于文件描述符不容易记忆,shell同时也给出了相应的文件名. 下面就是这些文件描述符及它们通常所 ...