[SCOI2012]奇怪的游戏
话说有没有跟我一样直接猜了一个最大值不会改变这样一个二乎乎的结论之后交上去保龄的呀
首先看到棋盘,选择相邻的格子,非常经典的黑白染色
显然那个二乎乎的结论是错的,随便就能\(hack\)了
于是我们二分这个最大值
如果当前二分出来的最大值是\(mid\),\(i+j\)为奇数,起点连\(mid-a[i][j]\)的边,否则向终点连\(mid-a[i][j]\)的边,相邻的格子连流量无穷的边,跑最大流看看起点连出去的边和连向终点的边是否都满流就好了
但是这样仅限于\(n\times m\)为偶数的情况
因为之后当\(n\times m\)为偶数的时候我们可以把整个棋盘整体加\(1\),因此存在单调性,于是可以二分
但是当\(n\times m\)为奇数的时候我们无论如何都得空至少一个
我们可以考虑一下最后棋盘变成了\(x\)
那么就会存在
\]
这个其实还是来源于上面的网络流建图,就是让两边流量平衡,由于\(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]奇怪的游戏的更多相关文章
- BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3352 Solved: 919[Submit][Stat ...
- Bzoj2756 [SCOI2012]奇怪的游戏
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3220 Solved: 886 Description ...
- [题目] Luogu P5038 [SCOI2012]奇怪的游戏
学习资料 -----1----- -----2----- P5038 [SCOI2012]奇怪的游戏 一道甚神但没用到高深模型的题 思路 没思路,看题解吧 代码 #include <iostre ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 网络流/二分
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1594 Solved: 396[Submit][Stat ...
- bzoj 2756 [SCOI2012]奇怪的游戏 二分+网络流
2756:[SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 4926 Solved: 1362[Submit][Stat ...
- bzoj2756: [SCOI2012]奇怪的游戏(网络流+分情况)
2756: [SCOI2012]奇怪的游戏 题目:传送门 题解: 发现做不出来的大难题一点一个网络流 %大佬 首先黑白染色(原来是套路...)染色之后就可以保证每次操作都一定会使黑白各一个各自的值加1 ...
- bzoj 2756: [SCOI2012]奇怪的游戏
Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...
- P5038 [SCOI2012]奇怪的游戏 二分+网络流
$ \color{#0066ff}{ 题目描述 }$ Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 \(N \times M\) 的棋盘上玩,每个格子有一个数.每次\(Blinker\)会 ...
- BZOJ2756:[SCOI2012]奇怪的游戏(最大流,二分)
Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...
- BZOJ 2756 SCOI2012 奇怪的游戏 最大流
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2756 Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N ...
随机推荐
- 关于在web端运行项目,eclipse报PermGen space错误
之前在网上也查到过许多解决的方法,但可能因为本人脸黑........也修改过eclipse文件目录中的相关配置文件,并没有得到相应的帮助,因此把自己的改正方法分享下: window-->pref ...
- JavaScript之Array
JavaScript是一门非常灵活的动态语言,涵盖的内容也挺多,<JavaScript高级程序设计>看了也有两遍,但是在实际开发的时候,还是有很多东西记不清,然后还得去翻书,特别是一些Ar ...
- 阿里云短信服务Java版
短信服务管理平台 https://dysms.console.aliyun.com/dysms.htm java短信发送API https://help.aliyun.com/document_ ...
- dojox.grid.DataGrid显示数据的方法(转)
第一种:数据存在本地或者已经写死的JSON对象中,不需要跟服务端进行数据传输 <%@ page language="java" contentType="text/ ...
- ANT DESIGN PRO 脚手架.... 懒人福音
早上在用蚂蚁组件,看到一个红红的 PRO , 什么鬼,点了看. https://pro.ant.design/index-cn 一脸懵逼, 中台前端??? 预览再看: 后台管理的demo , 脚手架 ...
- Spring Boot—13事务支持
pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- android之画板功能之橡皮擦 画笔大小和画笔颜色
第一展示设置画笔颜色的功能,第二展示设置画笔大小的颜色,而第三则展示橡皮擦的功能,这节将图标颜色设置为了蓝色,并且,增加了最左边的按钮(其实,就是在gridview中多增加了一个item). 下面分别 ...
- 重装系统,打开VS进行程序调试运行的时候 Unable to find manifest signing certificate in the certificate store
重装系统,打开VS进行程序调试运行的时候 Unable to find manifest signing certificate in the certificate store. 项目的属性-> ...
- 180415_判断闰年的思路及三种 java 实现
世纪年:能整除 100 的年份 普通年:不能整除 100 的年份 闰年:一年有 366 天,二月有 29 天 平年:一年有 365 天,二月有 28 天 对于世纪年:能整除 400 为闰年,否则为平年 ...
- idea 自定义视图
效果: 设置:!file:.iml&&!file:.idea//&&!file:.settings//*&&!file:.classpath&& ...