将网格分为两部分,方法是黑白染色,即判断(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 ;
}

最新文章

  1. tp框架,访问方式、空方法
  2. JavaScript高级程序设计-(2)基础概念
  3. maven更改编译环境的java版本
  4. 如何在EF CodeFirst中使用唯一约束(Unique)
  5. Linux 进程管理器 supervixor
  6. Win7-64bit系统下安装mysql的ODBC驱动
  7. transform: translateY(-50%) 实现元素垂直居中效果
  8. 9月java货车版速记
  9. android部分手机onclick事件触发2次
  10. ElastciSearch常用APi
  11. Oracle基本分组查询group by的使用
  12. 用到的Python运算符
  13. DES加密解密 与 Cookie的封装(C#与js互相加密解密)
  14. CentOS 6.5 开机启动指定服务
  15. json解析—Gson以及GsonFormat插件的运用
  16. shell 脚本示例
  17. Python监控服务器利器--psutil
  18. visual studio的试用版评估期已结束 解决办法
  19. 必修3第三章概率mindmaps
  20. Unity 游戏开发技巧集锦之创建部分光滑部分粗糙的材质

热门文章

  1. JSP-Runoob:JSP 状态码
  2. bzoj3661
  3. 设计模式 |备忘录模式(memento)
  4. C# 截取字符串——
  5. 第一个只出现一次的字符--java实现
  6. win快速搜索软件
  7. hbuilder中的 http://www.w3.org/TR/html4/strict.dtd
  8. Windows键盘驱动结构与消息机制--转
  9. [ NOIP 1998 ] TG
  10. html5——私有前缀