这道题提醒我,要有将棋盘黑白染色的意识,尤其是看到相邻格子这样的条件的时候,然后就是要用到与其有关的性质与特点以体现其作用,这道题就是用到了黑格子与白格子之间的关系进行的,其出发点是每次一定会给一个黑格子与一个白格子均加一,那么最后黑白格子所加量相同(最关键的地方)。
然后呢,还要观察,最终高度与行动次数一一对应,于是求解他们两个是等效的,然后发现如果最后高度确定,是很好验证是否可行的,就是方格下水道。进一步分析,当黑格与白格的数量不同那么最终高度一定,可以一下判解。当数量相同的时候关于最终高度是单调的,因为h可以,h+1也可以,所以这道题就这么解决了。
为什么我想不到啊(苣蒻++)。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define pos(a,b) (((a)-1)*m+(b))
typedef long long LL;
const int N=;
const int P=N*N;
const int E=P*;
const LL Inf=0x3f3f3f3f3f3f3f3fLL;
struct V{
int to,next;
LL f;
}c[E];
int head[P],t;
inline void add(int x,int y,LL z){
c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].f=z;
}
inline void clear(){
memset(head,,sizeof(head)),t=;
}
int n,m;
int S,T;
int deep[P],q[P],front,back;
inline bool bfs(){
memset(deep,,sizeof(deep));
front=back=,q[back++]=S,deep[S]=;
while(front!=back){
int x=q[front++];
for(int i=head[x];i;i=c[i].next)
if(c[i].f&&deep[c[i].to]==){
deep[c[i].to]=deep[x]+;
if(c[i].to==T)return true;
q[back++]=c[i].to;
}
}return false;
}
inline LL dfs(int x,LL v){
if(x==T||v==)return v;
LL ret=;
for(int i=head[x];i;i=c[i].next)
if(c[i].f&&deep[c[i].to]==deep[x]+){
LL f=dfs(c[i].to,std::min(c[i].f,v));
ret+=f,v-=f,c[i].f-=f,c[i^].f+=f;
if(v==)break;
}
if(ret==)deep[x]=;
return ret;
}
int cnt[];
LL sum[];
int max,val[N][N];
inline LL dinic(){
LL ret=;
while(bfs())ret+=dfs(S,Inf);
return ret;
}
inline bool check(LL ans){
clear();LL ret=;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
if((i+j)&){
if(i>)
add(pos(i,j),pos(i-,j),Inf),add(pos(i-,j),pos(i,j),);
if(j>)
add(pos(i,j),pos(i,j-),Inf),add(pos(i,j-),pos(i,j),);
if(i<n)
add(pos(i,j),pos(i+,j),Inf),add(pos(i+,j),pos(i,j),);
if(j<m)
add(pos(i,j),pos(i,j+),Inf),add(pos(i,j+),pos(i,j),);
add(S,pos(i,j),ans-val[i][j]),add(pos(i,j),S,);
ret+=ans-val[i][j];
}else
add(pos(i,j),T,ans-val[i][j]),add(T,pos(i,j),);
return ret==dinic();
}
inline void work1(){
if((sum[]-sum[])%(cnt[]-cnt[])!=){
puts("-1");return;
}
LL ans=(sum[]-sum[])/(cnt[]-cnt[]);
if(check(ans))
printf("%lld\n",(ans*n*m-(sum[]+sum[]))>>1LL);
else puts("-1");
}
inline void work2(){
if(sum[]!=sum[]){
puts("-1");return;
}
LL l=max,r=Inf/5000LL,mid,ans=;
while(l<=r){
mid=(l+r)>>;
if(check(mid))
ans=mid,r=mid-;
else
l=mid+;
}
if(ans==)puts("-1");
else printf("%lld\n",(ans*n*m-(sum[]+sum[]))>>1LL);
}
int main(){
int test;scanf("%d",&test);
while(test--){
scanf("%d%d",&n,&m);
memset(cnt,,sizeof(cnt));
memset(sum,,sizeof(sum));
max=,S=n*m+,T=n*m+;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
scanf("%d",&val[i][j]);
++cnt[(i+j)&],sum[(i+j)&]+=val[i][j];
max=std::max(max,val[i][j]);
}
if(cnt[]!=cnt[])work1();
else work2();
}return ;
}

【BZOJ 2756】[SCOI2012]奇怪的游戏 二分+最大流的更多相关文章

  1. bzoj 2756 [SCOI2012]奇怪的游戏 二分+网络流

    2756:[SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 4926  Solved: 1362[Submit][Stat ...

  2. BZOJ.2756.[SCOI2012]奇怪的游戏(二分 黑白染色 最大流ISAP)

    题目链接 \(Description\) \(Solution\) 这种题当然要黑白染色.. 两种颜色的格子数可能相同,也可能差1.记\(n1/n2\)为黑/白格子数,\(s1/s2\)为黑/白格子权 ...

  3. BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3352  Solved: 919[Submit][Stat ...

  4. BZOJ 2756: [SCOI2012]奇怪的游戏 网络流/二分

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 1594  Solved: 396[Submit][Stat ...

  5. BZOJ 2756 SCOI2012 奇怪的游戏 最大流

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2756 Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N ...

  6. bzoj 2756: [SCOI2012]奇怪的游戏

    Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...

  7. bzoj 2756 [SCOI2012]奇怪的游戏【二分+最大流】

    达成成就:为二分调参 !:多次memset的话要把数组大小开严格一点,否则会T 看到网格图,首先黑白染色. 注意到每次操作都是在一个黑格子和一个白格子上进行的,也就是说,最后黑格子数字和白格子数字和的 ...

  8. P5038 [SCOI2012]奇怪的游戏 二分+网络流

    $ \color{#0066ff}{ 题目描述 }$ Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 \(N \times M\) 的棋盘上玩,每个格子有一个数.每次\(Blinker\)会 ...

  9. 洛谷$P5038\ [SCOI2012]$奇怪的游戏 二分+网络流

    正解:二分+网络流 解题报告: 传送门$QwQ$ 这种什么,"同时增加",长得就挺网络流的$QwQ$?然后看到问至少加多少次,于是考虑加个二分呗?于是就大体确定了做题方向,用的网络 ...

随机推荐

  1. Linux命令备忘录: jobs 显示Linux中的任务列表及任务状态命令

    Linux jobs命令用法详解:显示Linux中的任务列表及任务状态命令 jobs命令用于显示Linux中的任务列表及任务状态,包括后台运行的任务.该命令可以显示任务号及其对应的进程号.其中,任务号 ...

  2. mac制作U盘启动器

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.所需工具及必要条件: 1. 首先需要一个大于16GB U盘. 2.电脑系统版本应该大于10.11.X(因为之前 ...

  3. python2.7练习小例子(十八)

    19):题目:一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程找出1000以内的所有完数.      #!/usr/bin/python # -*- ...

  4. Spring 框架控制器类方法可用的参数与返回类型

    参数类型 Spring 有内建的 HTTP 消息转换器用于部分简单类型之间的转换 标准 Servlet 类型:HttpServletRequest, HttpServletResponse, Http ...

  5. Oracle错误记录

    1 SQLPlus无法登陆oracle,PLSql可以登陆,报错ORA-12560 环境变量 右击计算机属性-->高级系统设置-->高级-->环境变量-->系统变量--> ...

  6. 联想ThinkPad S3-S440虚拟机安装,ubuntu安装,Hadoop(2.7.1)详解及WordCount运行,spark集群搭建

    下载ubuntu操作系统版本 ubuntu-14.10-desktop-amd64.iso(64位) 安装过程出现错误: This kernel requires an X86-64 CPU,but ...

  7. AR技术介绍(Located in Android)

    一,什么是AR 在说AR技术之前,先来说说VR. 虚拟现实(VR:Virtual Reality)是采用以计算机技术为核心的技术,生成逼真的视,听,触觉等一体化的虚拟环境,用户借助必要的设备以自然的方 ...

  8. 洛谷P3958 奶酪

    题目链接 这道题貌似可以用BFS来写吧qwq. 我用的是并查集,把联通的洞合并在同一个几何中,最后只需要判断是否存在上表面和下表面有相同集合的洞即可. 但是需要注意的是还有这样的一种情况:有一个大洞贯 ...

  9. 【C#】 反射

    [C#] 反射 目录 : http://msdn.microsoft.com/zh-cn/library/System.Reflection(v=vs.110).aspx System.Reflect ...

  10. 基于Mysql-Proxy实现Mysql的主从复制以及读写分离(下)

    基于Mysql-Proxy实现Mysql的主从复制以及读写分离(下) 昨天谈到了Mysql实现主从复制,但由于时间原因并未讲有关读写分离的实现,之所以有读写分离,是为了使数据库拥有双机热备功能,至于双 ...