题目

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

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

显然那个二乎乎的结论是错的,随便就能\(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. Eclipse中新建Java工程的三个JRE选项区别

    整理自:https://blog.csdn.net/wdjhzw/article/details/42086615 官方解释(链接) Use default JRE: When selected, t ...

  2. python学习之老男孩python全栈第九期_数据库day003知识点总结 —— MySQL数据库day3

    复习: 1. 增 insert into xx(name) values('root'),('xxx'); insert into xx(name) select id from tb1; 2. 自增 ...

  3. SQL Server删除表及删除表中数据的方法

    删除表的T-SQL语句为: drop table <表名> drop是丢弃的意思,drop table表示将一个表彻底删除掉. 删除表数据有两种方法:delete和truncate. de ...

  4. 一文理解JS的节流、防抖及使用场景

    函数防抖(debounce):在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时. 看一个

  5. 通过读写文本文件小结“关于python处理中文编码的问题”

    一.引言 无论学习什么程序语言,字符串这种数据类型总是着有非常重要.然而最近在学习python这门语言,想要显示中文,总是出现各种乱码.于是在网上查了很多资料,各说纷纭,我也尝试了许多的方法,有时候可 ...

  6. 【PyQt5 学习记录】007:改变窗口样式之一

    class MainWindow(QMainWindow): 2 def __init__(self, parent=None): 3 super(MainWindow, self).__init__ ...

  7. Django Redis存储session会话

    通常redis都是用来保存session.短信验证码.图片验证码等数据. 在django上使用redis,先要安装一个包: pip install django-redis==4.8.0(我用的dja ...

  8. python 事务

    事务命令 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 数据库开启事务命令 -- start transaction 开启事务 -- Rollback 回滚事务,即撤 ...

  9. C#判断奇偶数的函数

    // 现代流行的"程序员"public static bool IsOdd(int n) {     while (true)    {        switch (n)     ...

  10. mvc5中重命名项目的名称后,出现"找到多个与名为“Home”的控制器匹配的类型"

    1.已把项目中所有的Webapplication1改为了MvcMovie,但是运行后,还是报错: 找到多个与名为“Home”的控制器匹配的类型 2.已重新生成解决方安,还是不行. 解决方法:把bin文 ...