将网格分为两部分,方法是黑白染色,即判断(i+j)&1即可,分开后从白色格子向黑色格子连边,每个点需要四条(边界点可能更少),也就是每个格子周围的四个方向。之后将源点和汇点分别于黑白格子连边,边权即为点权,最后用总权值减去最小割即可。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue> using namespace std; #define INF 0x3f3f3f3f template<const int _n,const int _m>
struct Edge
{
struct Edge_base { int to,next,w; }e[_m]; int cnt,p[_n];
Edge() { clear(); }
void insert(const int x,const int y,const int z)
{ e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; }
int start(const int x) { return p[x]; }
void clear() { cnt=,memset(p,,sizeof(p)); }
Edge_base& operator[](const int x) { return e[x]; }
}; int n,m,N,SSS,TTT,a[][];
int level[],cur[];
Edge<,> e; bool Bfs(const int S)
{
int i,t;
queue<int> Q;
memset(level,,sizeof(level));
level[S]=;
Q.push(S);
while(!Q.empty())
{
t=Q.front(),Q.pop();
for(i=e.start(t);i;i=e[i].next)
{
if(!level[e[i].to] && e[i].w)
{
level[e[i].to]=level[t]+;
Q.push(e[i].to);
}
}
}
return level[TTT];
} int Dfs(const int S,const int bk)
{
if(S==TTT)return bk;
int rest=bk;
for(int &i=cur[S];i;i=e[i].next)
{
if(level[e[i].to]==level[S]+ && e[i].w)
{
int flow=Dfs(e[i].to,min(e[i].w,rest));
e[i].w-=flow;
e[i^].w+=flow;
if((rest-=flow)<=)break;
}
}
if(bk==rest)level[S]=;
return bk-rest;
} int Dinic()
{
int flow=;
while(Bfs(SSS))
{
memcpy(cur,e.p,sizeof(cur));
flow+=Dfs(SSS,0x3f3f3f3f);
}
return flow;
} int main()
{
freopen("grid.in","r",stdin);
freopen("grid.out","w",stdout); int i,j,Sum=; scanf("%d%d",&n,&m);
N=n*m;SSS=N+,TTT=SSS+;
for(i=;i<=n;++i)for(j=;j<=m;++j)
scanf("%d",&a[i][j]),Sum+=a[i][j];
for(i=;i<=n;++i)
{
for(j=;j<=m;++j)
{
int t=(i-)*m+j;
if(((i&) && !(j&)) || (!(i&) && (j&)))
{
e.insert(SSS,t,a[i][j]);
e.insert(t,SSS,);
if(i>)e.insert(t,t-m,INF),e.insert(t-m,t,);
if(i<n)e.insert(t,t+m,INF),e.insert(t+m,t,);
if(j>)e.insert(t,t-,INF),e.insert(t-,t,);
if(j<m)e.insert(t,t+,INF),e.insert(t+,t,);
}
else
{
e.insert(t,TTT,a[i][j]);
e.insert(TTT,t,);
if(i>)e.insert(t-m,t,INF),e.insert(t,t-m,);
if(i<n)e.insert(t+m,t,INF),e.insert(t,t+m,);
if(j>)e.insert(t-,t,INF),e.insert(t,t-,);
if(j<m)e.insert(t+,t,INF),e.insert(t,t+,);
}
}
} printf("%d\n",Sum-Dinic()); return ;
}

[网络流24题#9] [cogs734] 方格取数 [网络流,最大流最小割]的更多相关文章

  1. Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流)

    Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流) Description 给定有向图G=(V,E).设P是G的一个简单路(顶点不相 ...

  2. Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)

    Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流) Description W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行 ...

  3. BZOJ 1475: 方格取数( 网络流 )

    本来想写道水题....结果调了这么久!就是一个 define 里面少加了个括号 ! 二分图最大点权独立集...黑白染色一下 , 然后建图 : S -> black_node , white_no ...

  4. 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)

      HDU 1565 方格取数(1) 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的 ...

  5. [BZOJ1475]方格取数 网络流 最小割

    1475: 方格取数 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 512[Submit][Status][Discuss] ...

  6. HDU 1569 方格取数(2) (最小割)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  7. P2774 方格取数(网络流)

    https://www.luogu.com.cn/problem/P2774 在一个有 m×n 个方格的棋盘中,每个方格中有一个正整数. 现要从方格中取数,使任意2个数所在方格没有公共边,且取出的数的 ...

  8. LuoguP2774 方格取数问题(最小割)

    题目背景 none! 题目描述 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法.对于 ...

  9. 【PowerOJ1736&网络流24题】飞行员配对方案问题(最小割)

    题意: n<=100,要求输出方案 思路:准备把没刷的24题从头搞一遍 输出方案的话就在增广的时候记一下另一端的编号就好 #include<bits/stdc++.h> using ...

随机推荐

  1. createrepo

    [root@iio enp]# createrepo -g /enp/comps.xml .Spawning worker 0 with 1362 pkgsWorkers FinishedSaving ...

  2. CentOS 7.0 firewall防火墙关闭firewall作为防火墙,这里改为iptables防火墙

    CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙步骤: 1.先检查是否安装了: iptables service iptables status 2.安装ip ...

  3. No operations allowed after connection closed--转

    https://www.jianshu.com/p/1626d41572f2 Spring boot的单数据源配置比较简单,只需要在application.properties配置相关的jdbc连接的 ...

  4. sql语句优化:用join取代not in

    不要太多使用not in查询,最好用表连接来取代它.如: select ID,name from Table_A where ID not in (select ID from Table_B) 这句 ...

  5. C++中 list与vector的区别

    引用http://www.cnblogs.com/shijingjing07/p/5587719.html C++ vector和list的区别 1.vector数据结构vector和数组类似,拥有一 ...

  6. 【转】Java 集合系列02之 Collection架构

    概要 首先,我们对Collection进行说明.下面先看看Collection的一些框架类的关系图: Collection是一个接口,它主要的两个分支是:List 和 Set. List和Set都是接 ...

  7. CSS——font

    行高的量取方式: 1.第一行可设置margin-top值.然后将第一文字顶部到第二行文字顶部的值作为行高的值(要注意对齐方式) 2.将 3.电视上 font:12px/1.5//字体12px,行高1. ...

  8. codeforces_734C_二分

    C. Anton and Making Potions time limit per test 4 seconds memory limit per test 256 megabytes input ...

  9. Android之Fragment的优点和作用

    一:什么是Fragment 碎片.片段.其目的是为了解决不同屏幕分辩率的动态和灵活UI设计.大屏幕如平板小屏幕如手机,平板电脑的设计使得其有更多的空间来放更多的UI组件,而多出来的空间存放UI使其会产 ...

  10. C# 统计字符串出现的个数

    string str1 = "123AAA456AAAA789AAAAAAA1011"; string str2 = "123456789AAA23456789AAAA3 ...