Description

Blinker最近喜欢上一个奇怪的游戏。
这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数。每次 Blinker 会选择两个相邻
的格子,并使这两个数都加上 1。
现在 Blinker 想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同
一个数则输出-1。

Input

输入的第一行是一个整数T,表示输入数据有T轮游戏组成。
每轮游戏的第一行有两个整数N和M, 分别代表棋盘的行数和列数。
接下来有N行,每行 M个数。

Output

对于每个游戏输出最少能使游戏结束的次数,如果永远不能变成同一个数则输出-1。

Sample Input

2
2 2
1 2
2 3
3 3
1 2 3
2 3 4
4 3 2

Sample Output

2
-1

HINT

【数据范围】

对于30%的数据,保证  T<=10,1<=N,M<=8

对于100%的数据,保证  T<=10,1<=N,M<=40,所有数为正整数且小于1000000000

Source

一道很不错的网络流啊,一开始以为是所有数都变成最大的那个数,然后以为是个大水题,wa了之后觉得可以二分,结果又wa了;

看了题解之后发现自己简直mdzz;

首先看到这种题目的第一反应就是黑白染色,然后我们设黑点的数量为num1,黑点的权值和为sum1,白点的数量为num2,白点的权值和为sum2;

那么我们假设变为的数=x,那么num1*x-sum1=num2*x-sum2,如果num1!=num2,那么x可以直接解出来,x=(sum1-sum2)/(num1-num2);

如果num1=num2,因为每个点都能有匹配,那么答案满足可二分性,因为假如能变成x,那么对于k>=x,那么肯定也能变成k,因为可以先变成x,然后一对匹配就一直加;

所以对于这个num1=num2二分x就可以了;

把x求出来之后用最大流check:

//MADE BY QT666
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
typedef long long ll;
const int N=100050;
const int Inf=3e15;
int head[N],to[N],nxt[N],s[N],q[N],cnt=1,level[N],S,T;
ll F;
void Addedge(int x,int y,int z) {
to[++cnt]=y,s[cnt]=z,nxt[cnt]=head[x],head[x]=cnt;
}
void lnk(int x,int y,int z){
Addedge(x,y,z),Addedge(y,x,0);
}
bool bfs(){
for(int i=S;i<=T;i++) level[i]=0;
q[0]=S,level[S]=1;int t=0,sum=1;
while(t<sum){
int x=q[t++];
if(x==T) return 1;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(s[i]&&level[y]==0){
level[y]=level[x]+1;
q[sum++]=y;
}
}
}
return 0;
}
int dfs(int x,int maxf){
if(x==T) return maxf;
int ret=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];int f=s[i];
if(level[y]==level[x]+1&&f){
int minn=min(f,maxf-ret);
f=dfs(y,minn);
s[i]-=f,s[i^1]+=f,ret+=f;
if(ret==maxf) break;
}
}
if(!ret) level[x]=0;
return ret;
}
void Dinic(){
F=0;while(bfs()) F+=dfs(S,Inf);
}
bool check(){
for(int i=head[S];i;i=nxt[i]) if(s[i]) return 0;
for(int i=head[T];i;i=nxt[i]) if(s[i^1]) return 0;
return 1;
}
int a[100][100],maxn,xh[100][100];
int mx[]={1,-1,0,0},my[]={0,0,1,-1},n,m,tt,tot;
bool judge(int mid){
memset(head,0,sizeof(head));cnt=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if((i+j)%2==0){
lnk(S,xh[i][j],mid-a[i][j]);
for(int k=0;k<4;k++){
int x=i+mx[k],y=j+my[k];
if(x>=1&&x<=n&&y>=1&&y<=m) lnk(xh[i][j],xh[x][y]+tt,Inf);
}
}
else lnk(xh[i][j]+tt,T,mid-a[i][j]);
}
}
Dinic();return check();
}
main(){
int t;scanf("%lld",&t);
while(t--){
scanf("%lld%lld",&n,&m);maxn=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%lld",&a[i][j]);maxn=max(maxn,a[i][j]);
}
}
tt=0,tot=0;int sum1=0,sum2=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if((i+j)%2==0) xh[i][j]=++tt,sum1+=a[i][j];
else xh[i][j]=++tot,sum2+=a[i][j];
}
}
T=tt+tot+1;
if(tt!=tot){
int mid=(sum1-sum2)/(tt-tot);
if(judge(mid)) cout<<F<<endl;
else puts("-1");
}
if(tt==tot){
int l=maxn,r=2e9,ans=-1;
while(l<=r){
int mid=(l+r)>>1;
if(judge(mid)) ans=F,r=mid-1;
else l=mid+1;
}
cout<<ans<<endl;
}
}
return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  7. Bzoj2756 [SCOI2012]奇怪的游戏

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

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

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

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

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

随机推荐

  1. 二维,多维数组排序array_multisort()函数的使用

    对于数组的排序,很很多方法:随便百度了一下 sort() - 以升序对数组排序 rsort() - 以降序对数组排序 asort() - 根据值,以升序对关联数组进行排序 ksort() - 根据键, ...

  2. 十五、Hadoop学习笔记————Zookeeper客户端的使用

    timeout表示会话超时时间,zookeeper靠与客户的心跳来判断会话是否有效(单位毫秒), -r为只读,表示zookeeper如果与半数以上服务器失去连接则会停止服务,如果有-r参数,则会继续保 ...

  3. 【微服务】之五:轻松搞定SpringCloud微服务-调用远程组件Feign

    上一篇文章讲到了负载均衡在Spring Cloud体系中的体现,其实Spring Cloud是提供了多种客户端调用的组件,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使 ...

  4. Android破解学习之路(一)——简单的登录破解

    最近突然心血如潮开始学了Android破解,初入门,便是将经验记录下来. 准备工作: 1.一个登录简单APP 在我们破解之前,我们需要做一个简单的登录APP,输入相应的账号与密码便是弹出登录成功的对话 ...

  5. Spring Cloud Ribbon 整合 Hystrix

    在前面随笔 Spring Cloud 之 Ribbon 的ribbon工程基础上进行改造 1.pom.xml 加入依赖 <dependency> <groupId>org.sp ...

  6. hdoj 4325 Flowers 线段树+离散化

    hdoj 4325 Flowers 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4325 思路: 直接线段树,按照花的开放区间的大小建树,要注意虽然 ...

  7. 360提供的php防注入代码

    <?php //Code By Safe3 function customError($errno, $errstr, $errfile, $errline) { echo "< ...

  8. UWP 显示图片到Image控件

    要想显示图片,前提是要有一个空间的啦 <Image x:Name="imageHidden"/> 然后一个响应选择图片得事件,注意使用asynchronous方法哦 F ...

  9. win10 mysql详尽安装教程

    我的电脑系统是win10 64位系统 我安装mysql不下5次,装好了又卸,卸了又装,看了老多篇文章和博客,非常感谢博主的无私帮助,以下是这些博主的文章: https://www.cnblogs.co ...

  10. php的过滤器功能

    1.简介 PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入. 1.1 外部数据: 来自表单的输入数据 Cookies Web services data 服务器变量 数据库查询结果 1 ...