luogu P2774 方格取数问题
有限制的问题,显然考虑全选再根据限制去掉的想法较优,我们发现一个点四周的点受限,其x或者y差一,也就是说奇偶性不同,那我们可以将其分成白点和黑点,就变成了最小割的问题,将每个白点向受限制的黑点连边,capacity为INF,每个黑点向汇点连边,capacity为该点的值,同理,源点向每个白点连边,这样受限的每一组之间都只会选出一个最小的来,通过capacity的限制来实现,最大流=最小割,将总和减去最小割(每一组最小的)就是答案
每一组黑白点,capacity来限制最小权,转换求最小割
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL; const int maxm = 1e5+;
const int INF = 0x3f3f3f3f;
const int dx[] = {, -, , };
const int dy[] = {, , , -}; struct edge{
int u, v, cap, flow, nex;
} edges[maxm]; int head[maxm], cur[maxm], cnt, level[], buf[][], num[][], ID; void init() {
memset(head, -, sizeof(head));
} void add(int u, int v, int cap) {
edges[cnt] = edge{u, v, cap, , head[u]};
head[u] = cnt++;
} void addedge(int u, int v, int cap) {
add(u, v, cap), add(v, u, );
} void bfs(int s) {
memset(level, -, sizeof(level));
queue<int> q;
level[s] = ;
q.push(s);
while(!q.empty()) {
int u = q.front();
q.pop();
for(int i = head[u]; i != -; i = edges[i].nex) {
edge& now = edges[i];
if(now.cap > now.flow && level[now.v] < ) {
level[now.v] = level[u] + ;
q.push(now.v);
}
}
}
} int dfs(int u, int t, int f) {
if(u == t) return f;
for(int& i = cur[u]; i != -; i = edges[i].nex) {
edge& now = edges[i];
if(now.cap > now.flow && level[u] < level[now.v]) {
int d = dfs(now.v, t, min(f, now.cap - now.flow));
if(d > ) {
now.flow += d;
edges[i^].flow -= d;
return d;
} }
}
return ;
} int dinic(int s, int t) {
int maxflow = ;
for(;;) {
bfs(s);
if(level[t] < ) break;
memcpy(cur, head, sizeof(head));
int f;
while((f = dfs(s, t, INF)) > )
maxflow += f;
}
return maxflow;
} void run_case() {
int m, n;
LL sum = ;
init();
cin >> n >> m;
int s = , t = m*n+;
for(int i = ; i <= n; ++i) {
for(int j = ; j <= m; ++j) {
cin >> buf[i][j];
sum += buf[i][j];
num[i][j] = ++ID;
if((i+j)%==) addedge(s, ID, buf[i][j]);
else addedge(ID, t, buf[i][j]);
}
}
for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) {
if((i+j)%==) continue;
for(int k = ; k < ; ++k) {
int nx = i+dx[k], ny = j+dy[k];
if(nx > n || nx < || ny > m || ny < ) continue;
addedge(num[i][j], num[nx][ny], INF);
}
}
sum -= dinic(s, t);
cout << sum;
} int main() {
ios::sync_with_stdio(false), cin.tie();
run_case();
cout.flush();
return ;
}
luogu P2774 方格取数问题的更多相关文章
- P2774 方格取数问题 网络最大流 割
P2774 方格取数问题:https://www.luogu.org/problemnew/show/P2774 题意: 给定一个矩阵,取出不相邻的数字,使得数字的和最大. 思路: 可以把方格分成两个 ...
- P2774 方格取数问题(网络流)
P2774 方格取数问题 emm........仔细一看,这不是最大权闭合子图的题吗! 取一个点$(x,y)$,限制条件是同时取$(x,y+1),(x,y-1),(x+1,y),(x-1,y)$,只不 ...
- 洛谷 P2774 方格取数问题 解题报告
P2774 方格取数问题 题目背景 none! 题目描述 在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...
- Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)
Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流) Description 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从 ...
- P2774 方格取数问题 网络流重温
P2774 方格取数问题 这个题目之前写过一次,现在重温还是感觉有点难,可能之前没有理解透彻. 这个题目要求取一定数量的数,并且这些数在方格里面不能相邻,问取完数之后和最大是多少. 这个很好的用了网络 ...
- P2774 方格取数问题 网络流
题目: P2774 方格取数问题 题目背景 none! 题目描述 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...
- P2774 方格取数问题(最小割)
P2774 方格取数问题 一看题目便知是网络流,但由于无法建图.... 题目直说禁止那些条件,这导致我们直接建图做不到,既然如此,我们这是就要逆向思维,他禁止那些边,我们就连那些边. 我们将棋盘染色, ...
- P2774 方格取数(网络流)
https://www.luogu.com.cn/problem/P2774 在一个有 m×n 个方格的棋盘中,每个方格中有一个正整数. 现要从方格中取数,使任意2个数所在方格没有公共边,且取出的数的 ...
- P2774 方格取数问题
题目背景 none! 题目描述 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法.对于 ...
随机推荐
- 学习笔记(24)- plato-训练中文模型
先处理中文语料.参考上篇笔记 1. 准备model_definition_file文件 官方文档给了例子, plato/example/config/ludwig/metalWOZ_seq2seq_l ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) - D2. Optimal Subsequences (Hard Version)(主席树)
题意:一共有$n$个数,$m$次询问,每次询问包括$k.pos$两个数,需要你从这$n$个数里面找出$k$个数,使得他们的总和最大,如果有多种情况,找出序号字典序最小的一组,然后输出这个序列中第$po ...
- web前端安全性
跨站脚本攻击(XSS攻击) XSS(Cross Site Scripting),跨站脚本攻击.XSS是常见的Web攻击技术之一.所谓的跨站脚本攻击指得是:恶意攻击者往Web页面里注入恶意Script代 ...
- canvas的beginPath和closePath
https://www.cnblogs.com/xuehaoyue/p/6549682.html https://segmentfault.com/a/1190000010330319 https:/ ...
- Centos610 Oracle 监听文件配置参考
lister.ora配置参考 # listener.ora Network Configuration File: /home/oracle/app/oracle/product//dbhome_1/ ...
- proto school tutorial: blog: lesson 1
https://proto.school/#/blog/01 我们现在希望:把一个post 和他的作者联系起来. 从之前的教程here中,你可以知道, 一个cid 就是代表一个link 比如: { l ...
- 学习笔记(5)- ubuntu对话语料
The Ubuntu Dialogue Corpus: A Large Dataset for Research in Unstructured Multi-Turn Dialogue Systems ...
- vs2013设置不生成.sdf和ipch文件
转载:https://blog.csdn.net/sinat_23338865/article/details/53393760 使用VS2013建立解决方案时,会生成SolutionName.sdf ...
- linux Shell(待学)
2. Shell 2.1 简介 shell脚本执行方式Shell 是一个用 C 语言编写的程序,通过 Shell 用户可以访问操作系统内核服务.它类似于 DOS 下的 command 和后来的 cmd ...
- JavaScript中关于隐式转换的一些总结
JavaScript运算符中的隐式转换规律:一.递增递减运算符(前置.后置)1.如果包含的是有效数字字符串或者是有效浮点数字符串,则会将字符串转换(Number())为数值,再进行加减操作,返回值的类 ...