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

    1:自定义接口编程 对于自定义接口最关键就是写接口文档,在接口文档中规定具体的请求地址以及方式,还有具体的参数信息 2:接口文档编写 请求地址 http://jxshop.com/Api/login ...

  2. Centos安装docker#避免很多坑

    采用yum方式安装 安装: step 1: 安装必要的一些系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 Step 2 ...

  3. Django的aggregate()和annotate()函数的区别

    aggregate() aggregate()为所有的QuerySet生成一个汇总值,相当于Count().返回结果类型为Dict. annotate() annotate()为每一个QuerySet ...

  4. DJANGO2.0 关联表的必填 ON_DELETE

    DJANGO2.0 关联表的必填 ON_DELETE 参数的含义 - BUXIANGHEJIU 的博客 - CSDN 博客 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blo ...

  5. Ruby字符串的一些方法

    最近因为公司需求开始看ruby,先从ruby的基本数据类型开始看 看到ruby的字符串类型string,发现ruby中的字符串单双引号是不一样的,这点和Python有那么点不一样 主要是我们对字符串进 ...

  6. MySQL共享表空间扩容

    一.什么是共享表空间和独占表空间 共享表空间以及独占表空间都是针对数据的存储方式而言的. 共享表空间: 某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目 ...

  7. 在WPF中自定义控件(3) CustomControl (上)

    原文:在WPF中自定义控件(3) CustomControl (上) 在WPF中自定义控件(3) CustomControl (上)                              周银辉 ...

  8. php长整型完整输出

    今天调用webservice时返回一个字段是int64 长整型 原始的数值应该是 190000002101056096 而php返回时转成 1.9000000210106E+17 当传入另一个接口就报 ...

  9. 【面试题】2018年最全Java面试通关秘籍第五套!

    [面试题]2018年最全Java面试通关秘籍第五套! 原创 2018-04-26 徐刘根 Java后端技术 第一套:<2018年最全Java面试通关秘籍第一套!> 第二套:<2018 ...

  10. 为什么在默认情况下无法修改被block捕获的变量? __block都做了什么?

    默认情况下,block里面的变量,拷贝进去的是变量的值,而不是指向变量的内存的指针.使用__block修饰后的变量,拷贝到block里面的就是指向变量的指针,所以我们就可以修改变量的值.