题目

话说有没有跟我一样直接猜了一个最大值不会改变这样一个二乎乎的结论之后交上去保龄的呀

首先看到棋盘,选择相邻的格子,非常经典的黑白染色

显然那个二乎乎的结论是错的,随便就能\(hack\)了

于是我们二分这个最大值

如果当前二分出来的最大值是\(mid\),\(i+j\)为奇数,起点连\(mid-a[i][j]\)的边,否则向终点连\(mid-a[i][j]\)的边,相邻的格子连流量无穷的边,跑最大流看看起点连出去的边和连向终点的边是否都满流就好了

但是这样仅限于\(n\times m\)为偶数的情况

因为之后当\(n\times m\)为偶数的时候我们可以把整个棋盘整体加\(1\),因此存在单调性,于是可以二分

但是当\(n\times m\)为奇数的时候我们无论如何都得空至少一个

我们可以考虑一下最后棋盘变成了\(x\)

那么就会存在

\[x\times num_{\text{奇}}-sum_{\text{奇}}=x\times num_{\text{偶}}-sum_{\text{偶}}
\]

这个其实还是来源于上面的网络流建图,就是让两边流量平衡,由于\(num_{\text{奇}}!=num_{\text{偶}}\),我们可以直接解得

\[x=\frac{sum_{\text{奇}}-sum_{\text{偶}}}{num_{\text{奇}}-num_{\text{偶}}}
\]

由于我们不能再让棋盘整体加了,于是直接判断\(x\)是否合法就好了

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=2005;
const LL inf=5e12;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
std::queue<int> q;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
int head[maxn],d[maxn],id[51][51],S,T,num;
int n,m,a[51][51],pd[maxn],cur[maxn];
struct E{int v,nxt;LL f;}e[maxn*40];
inline void C(int x,int y,LL f) {
e[++num].v=y;e[num].nxt=head[x];
head[x]=num;e[num].f=f;
}
inline void add(int x,int y,LL f) {C(x,y,f),C(y,x,0);}
inline int BFS() {
for(re int i=S;i<=T;i++) d[i]=0,cur[i]=head[i];
d[S]=1,q.push(S);
while(!q.empty()) {
int k=q.front();q.pop();
for(re int i=head[k];i;i=e[i].nxt)
if(e[i].f&&!d[e[i].v]) d[e[i].v]=d[k]+1,q.push(e[i].v);
}
return d[T];
}
LL dfs(int x,LL now) {
if(x==T||!now) return now;
LL flow=0,ff;
for(re int& i=cur[x];i;i=e[i].nxt)
if(d[e[i].v]==d[x]+1) {
ff=dfs(e[i].v,min(now,e[i].f));
if(ff<=0) continue;
now-=ff,flow+=ff,e[i].f-=ff,e[i^1].f+=ff;
if(!now) break;
}
return flow;
}
inline int check(LL mx) {
num=1;memset(head,0,sizeof(head));
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++) {
pd[id[i][j]]=num+1;
if((i+j)&1) add(S,id[i][j],mx-a[i][j]);
else add(id[i][j],T,mx-a[i][j]);
if(mx<a[i][j]) return 0;
}
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++) {
if(!((i+j)&1)) continue;
for(re int k=0;k<4;k++) {
int x=i+dx[k],y=j+dy[k];
if(x<1||y<1||x>n||y>m) continue;
add(id[i][j],id[x][y],inf);
}
}
while(BFS()) dfs(S,inf);
int flag=1;
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++)
flag&=(e[pd[id[i][j]]].f==0);
return flag;
}
int main() {
int Test=read();
while(Test--) {
n=read(),m=read();T=0;
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++) a[i][j]=read();
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++) id[i][j]=++T;
++T;
LL s[2],tot[2];
tot[0]=tot[1]=s[0]=s[1]=0;
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++)
tot[(i+j)&1]++,s[(i+j)&1]+=a[i][j];
if((n*m)&1) {
LL x=(s[1]-s[0])/(tot[1]-tot[0]);
if(check(x))
printf("%lld\n",x*tot[1]-s[1]);
else puts("-1");
}
else {
LL ans=-1,l=1,r=2e9;
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++) l=max(l,a[i][j]);
while(l<=r) {
LL mid=l+r>>1;
if(check(mid)) r=mid-1,ans=mid;
else l=mid+1;
}
if(ans==-1) puts("-1");
else printf("%lld\n",ans*tot[1]-s[1]);
}
}
return 0;
}

[SCOI2012]奇怪的游戏的更多相关文章

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

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

  2. Bzoj2756 [SCOI2012]奇怪的游戏

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3220  Solved: 886 Description ...

  3. [题目] Luogu P5038 [SCOI2012]奇怪的游戏

    学习资料 -----1----- -----2----- P5038 [SCOI2012]奇怪的游戏 一道甚神但没用到高深模型的题 思路 没思路,看题解吧 代码 #include <iostre ...

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

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

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

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

  6. bzoj2756: [SCOI2012]奇怪的游戏(网络流+分情况)

    2756: [SCOI2012]奇怪的游戏 题目:传送门 题解: 发现做不出来的大难题一点一个网络流 %大佬 首先黑白染色(原来是套路...)染色之后就可以保证每次操作都一定会使黑白各一个各自的值加1 ...

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

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

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

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

  9. BZOJ2756:[SCOI2012]奇怪的游戏(最大流,二分)

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

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

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

随机推荐

  1. [日常] Go语言圣经-GIF动画练习语法

    1.常量声明的值必须是一个数字值.字符串或者一个固定的boolean值.2.常量声明和变量声明一般都会出现在包级别3.[]color.Color{...}生成的是一个slice切片和gif.GIF{. ...

  2. Mapped Statements collection does not contain value for 问题的解决

    在做SSM项目的时候,遇到MyBatis抛出的一个异常: Mapped Statements collection does not contain value for org.lyk.vo.mapp ...

  3. UNIX高手应该保持的习惯

    UNIX 高手的 10 个习惯 克服不良的 UNIX 使用模式 采用 10 个能够提高您的 UNIX® 命令行效率的好习惯——并在此过程中摆脱不良的使用模式.本文循序渐进地指导您学习几项用于命令行操作 ...

  4. java 之DelayQueue实际运用示例

    在学习Java 多线程并发开发过程中,了解到DelayQueue类的主要作用:是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走. ...

  5. jQuery基础(鼠标事件,表单事件,键盘事件,自定义事件 篇)

    1.jQuery鼠标事件之click与dbclick事件   方法一:$ele.click()(不带参数)   <div id="test">点击触发<div&g ...

  6. jQuery箭头切换图片 - 学习笔记

    jQuery箭头切换图片 布局 3d位移 变形原点 jQuery transform:translate3d(x,y,z):        x 代表横向坐标移向量的长度       y 代表纵向坐标移 ...

  7. Git学习 之 安装

    1.官网下载 https://git-scm.com/downloads 2.修改安装目标路径,其他默认安装 3.通过系统管理员身份打开cmd,输入git 检查是否安装成功

  8. 在已配置成功的opencv3.2.0下配置opencv_contrib模块

    简介: 之前在Ubuntu下配置OpenCV时,因为对opencv3..0不是特别了解,没有把opencv_contrib进行安装,这里提醒大家尽量要一次性安装完毕,减少不必要的麻烦. .0文件夹 ( ...

  9. 对抗网络GAN的应用实例

      https://sigmoidal.io/beginners-review-of-gan-architectures/ 嗨,大家好!像许多追随AI进展的人一样,我无法忽略生成建模的最新进展,尤其是 ...

  10. 优雅的实现多类型列表的Adapter

    1引言 在开发中经常会遇到,一个列表(RecyclerView)中有多种布局类型的情况.前段时间,看到了这篇文章 [译]关于 Android Adapter,你的实现方式可能一直都有问题(http:/ ...