题目大意:给你一个$n\times m$的方格,要求你从中选择一些数,其中没有相邻两个数,使得最后和最大

题解:网络流,最小割,发现相邻的两个点不可以同时选择,进行黑白染色,原点向黑点连一条容量为点权的边,白点向汇点连一条容量为点权的边,黑点向周围一圈的白点连容量为$inf$的边,总权值减去跑出来的最小割就是答案。

卡点:

C++ Code:

#include <algorithm>
#include <cstdio>
#include <cctype>
namespace __IO {
namespace R {
int x, ch;
inline int read() {
ch = getchar();
while (isspace(ch)) ch = getchar();
for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
return x;
}
}
}
using __IO::R::read; #define maxn 100010
#define maxm (maxn << 3)
const int inf = 0x3f3f3f3f; int n, m, sum;
namespace Network_Flow {
int st, ed, MF;
int head[maxn], cnt = 1;
struct Edge {
int to, nxt, w;
} e[maxm << 1];
inline void addedge(int a, int b, int c) {
e[++cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
e[++cnt] = (Edge) {a, head[b], 0}; head[b] = cnt;
} int GAP[maxn], d[maxn], lst[maxn];
int q[maxn], h, t;
void init() {
GAP[d[ed] = 1] = 1;
for (int i = st; i <= ed; i++) lst[i] = head[i];
q[h = t = 0] = ed;
while (h <= t) {
int u = q[h++];
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (!d[v]) {
d[v] = d[u] + 1;
GAP[d[v]]++;
q[++t] = v;
}
}
}
}
int dfs(int u, int low) {
if (!low || u == ed) return low;
int w, res = 0;
for (int &i = lst[u]; i; i = e[i].nxt) if (e[i].w) {
int v = e[i].to;
if (d[u] == d[v] + 1) {
w = dfs(v, std::min(low, e[i].w));
res += w, low -= w;
e[i].w -= w, e[i ^ 1].w += w;
if (!low) return res;
}
}
if (!(--GAP[d[u]])) d[st] = ed + 1;
++GAP[++d[u]], lst[u] = head[u];
return res;
}
void ISAP(int __st, int __ed) {
st = __st, ed = __ed;
init();
while (d[st] <= ed) MF += dfs(st, inf);
}
}
using Network_Flow::addedge; inline int get(int x, int y) {return (x - 1) * m + y;}
const int D[2][4] = {{0, 1, 0, -1}, {1, 0, -1, 0}};
inline bool over_range(int x, int y) {
return x < 1 || x > n || y < 1 || y > m;
}
int main() {
n = read(), m = read();
int st = 0, ed = n * m + 1;
for (int i = 1, x, pos; i <= n; i++) {
for (int j = 1; j <= m; j++) {
sum += x = read(), pos = get(i, j);
if (i + j & 1) {
addedge(st, pos, x);
for (int k = 0; k < 4; k++) {
int __x = i + D[0][k], __y = j + D[1][k];
if (!over_range(__x, __y)) addedge(pos, get(__x, __y), inf);
}
} else addedge(pos, ed, x);
}
}
Network_Flow::ISAP(st, ed);
printf("%d\n", sum - Network_Flow::MF);
return 0;
}

  

[洛谷P2774]方格取数问题的更多相关文章

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

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

  2. 洛谷 - P2774 - 方格取数问题 - 二分图最大独立点集 - 最小割

    https://www.luogu.org/problemnew/show/P2774 把两个相邻的节点连边,这些边就是要方便最小割割断其他边存在的,容量无穷. 这种类似的问题的话,把二分图的一部分( ...

  3. 洛谷P2774 方格取数问题(最小割)

    传送门 考虑一下,答案就是全局和减去舍弃和 不难发现,如果我们按行数+列数的奇偶性分为两类,那么每一类中的数必然互不相邻 那么我们把原图的点分为黑点和白点两类,原地向白点连边,黑点向汇点连边,容量为点 ...

  4. 洛谷P2774 方格取数问题(最小割)

    题意 $n \times m$的矩阵,不能取相邻的元素,问最大能取多少 Sol 首先补集转化一下:最大权值 = sum - 使图不连通的最小权值 进行黑白染色 从S向黑点连权值为点权的边 从白点向T连 ...

  5. 洛谷 [P2774] 方格取数问题

    二分图最大点权独立集 通过题目描述我们可以很明显的看出要通过二分图建模,二分图求最大独立点集很容易,就是建立二分图求n-最小割,然而这里加入了权值,而且权值是在点上的,那么我们对于每个点连一条到源点或 ...

  6. 洛谷 P2774 方格取数问题【最小割】

    因为都是正整数,所以当然取得越多越好.先把所有点权加起来,黑白染色后,s向所有黑点连流量为点权的边,所有白点向t连流量为点权的边,然后黑点向相邻的四个白点连流量为inf的边,表示不可割,这样一来,对于 ...

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

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

  8. 洛谷 P1004 方格取数 题解

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

  9. 洛谷 P1004 方格取数 【多进程dp】

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

随机推荐

  1. 【forEach控制器】-(针对,在不知道取到得参数有多少?但是要全部执行每一条的情况)

    1.使用json提取器,提取全部参数 2.设置forEach控制器,他会自己把json提起器,取到得所有值,全部使用一次再停止. z

  2. 数据库Mysql的学习(四)-表的记录操作

    ,);//指定插入的顺序 ,);//按照默认的插入 ,),(,)(,);//同时插入多条数据 //将查询结果插入表中 CREATE TABLE TEXT( category_id INT PRIMAR ...

  3. Java基础知识:Java实现Map集合二级联动1

    Java实现Map集合二级联动 Map集合可以保存键值映射关系,这非常适合本实例所需要的数据结构,所有省份信息可以保存为Map集合的键,而每个键可以保存对应的城市信息,本实例就是利用Map集合实现了省 ...

  4. 正则表达式 和 re 模块

    正则表达式究竟是什么? 在一些网站注册的时候需要输入手机号码,当你输入一个错误的手机号码的时候,会提示你输入的手机号码格式错误 那么他究竟是如何判断的呢? 我们用Python代码进行表示: phone ...

  5. 棋盘问题:dfs

    Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子 ...

  6. Java开发中用的比较多的数据结构

    java 中几种常用数据结构 2016年07月11日 09:11:27 阅读数:83211 标签: 数据结构java 更多 个人分类: 自行学习   JAVA中常用的数据结构(java.util. 中 ...

  7. CVPR2018 关于视频目标跟踪(Object Tracking)的论文简要分析与总结

    本文转自:https://blog.csdn.net/weixin_40645129/article/details/81173088 CVPR2018已公布关于视频目标跟踪的论文简要分析与总结 一, ...

  8. leetcode个人题解——#24 Swap Nodes in Pairs

    因为不太熟悉链表操作,所以解决方法烦了点,空间时间多有冗余. 代码中l,r分别是每一组的需要交换的左右指针,temp是下一组的头指针,用于交换后链接:res是交换后的l指针,用于本组交换后尾指针在下一 ...

  9. NMAP-主机扫描

    1.全面扫描 2.扫描指定段 3.ping扫描 只进行ping操作,十分隐蔽 4.无ping扫描 适用于防火墙禁止ping 5.TCP SYN扫描 6.TCP ACK扫描 7.UDP扫描 8.ICMP ...

  10. 八:The YARN Timeline Server

    一.Overview 介绍     yarn timeline server用于存储和检查应用程序过去和现在的信息(比如job history server).有两个功能: 1.Persisting ...