2756:[SCOI2012]奇怪的游戏

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 4926  Solved: 1362
[Submit][Status][Discuss]

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

对棋盘进行黑白染色
设黑格个数为num1 数值和为sum1
设白格个数为num1 数值和为sum1

设最后都变为x

num1 * x – sum1 = num2 * x – sum2
x = (sum1 – sum2) / (num1 – num2)
当num1 ≠ num2时 可以解出 x 再用网络流check即可

对于num1 = num2时 可以发现 对于一个合法的x k>=x都是一个合法的解
因为num1 = num2 => (num1 + num2) % 2 == 0 可以构造一层的满覆盖
所以可以二分x 然后用网络流check

建图:
如果点k为白
建边(s, k, x – v[k])
如果为黑
建边(k, t, x – v[k])
对相邻点u、v (u为白)
建边 (u, v, inf)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath> #define inf (1LL<<50)
#define pa pair<int,int>
#define ll long long
#define p(x,y) (x-1)*m+y
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} ll s0,s1;
int c0,c1;
int test,n,m,cnt,S,T;
int xx[]={,,,-},yy[]={,-,,};
int a[][];
int last[],h[],q[],cur[];
bool color[][];
struct edge{
int to,next;ll v;
}e[]; void insert(int u,int v,ll w)
{
e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;
e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;e[cnt].v=;
}
bool bfs()
{
int head=,tail=;
memset(h,-,sizeof(h));
q[]=S;h[S]=;
while(head!=tail)
{
int now=q[head];head++;
for(int i=last[now];i;i=e[i].next)
if(e[i].v&&h[e[i].to]==-)
{
h[e[i].to]=h[now]+;
q[tail++]=e[i].to;
}
}
return h[T]!=-;
}
ll dfs(int x,ll f)
{
if(x==T)return f;
ll w,used=;
for(int i=cur[x];i;i=e[i].next)
if(h[e[i].to]==h[x]+)
{
w=dfs(e[i].to,min(f-used,e[i].v));
e[i].v-=w;e[i^].v+=w;
if(e[i].v)cur[x]=i;
used+=w;if(used==f)return f;
}
if(!used)h[x]=-;
return used;
}
ll dinic()
{
ll tmp=;
while(bfs())
{
for(int i=S;i<=T;i++)cur[i]=last[i];
tmp+=dfs(S,inf);
}
return tmp;
}
bool check(ll x)
{
memset(last,,sizeof(last));
cnt=;S=;T=n*m+;
ll tot=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(color[i][j])
{
insert(S,p(i,j),x-a[i][j]);tot+=x-a[i][j];
for(int k=;k<;k++)
{
int nowx=i+xx[k],nowy=j+yy[k];
if(nowx<||nowy<||nowx>n||nowy>m)continue;
insert(p(i,j),p(nowx,nowy),inf);
}
}
else insert(p(i,j),T,x-a[i][j]);
if(dinic()==tot)return ;
return ;
}
int main()
{
test=read();
while(test--)
{
c0=c1=s0=s1=;
n=read();m=read();
int mx=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
a[i][j]=read(),color[i][j]=(i+j)&;
mx=max(mx,a[i][j]);
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(color[i][j])s1+=a[i][j],c1++;
else s0+=a[i][j],c0++;
if(c0!=c1)
{
ll x=(s0-s1)/(c0-c1);
if(x>=mx)
if(check(x))
{
printf("%lld\n",x*c1-s1);
continue;
}
puts("-1");
}
else
{
if(s0!=s1)
{
puts("-1");
continue;
}
ll l=mx,r=inf;
while(l<=r)
{
ll mid=(l+r)>>;
if(check(mid))r=mid-;
else l=mid+;
}
printf("%lld\n",(ll)l*c1-s1);
}
}
}

bzoj 2756 [SCOI2012]奇怪的游戏 二分+网络流的更多相关文章

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

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

  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: 3352  Solved: 919[Submit][Stat ...

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

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

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

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

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

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

  7. 洛谷$P5038\ [SCOI2012]$奇怪的游戏 二分+网络流

    正解:二分+网络流 解题报告: 传送门$QwQ$ 这种什么,"同时增加",长得就挺网络流的$QwQ$?然后看到问至少加多少次,于是考虑加个二分呗?于是就大体确定了做题方向,用的网络 ...

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

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

  9. BZOJ2756 [SCOI2012]奇怪的游戏 【网络流 + 二分】

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

随机推荐

  1. anaconda 安装opencv win10

    直接在命令窗口里面运行:pip install opencv-python即可.

  2. Android Studio modify language level to Java 8

    If you need use lambda, should modify language level File -> Project Structure -> app -> Pr ...

  3. Linux 之vi与vim

    vi 三种模式: 『一般模式』: 光标 『编辑模式』:i,o,a,r 『指令列命令模式』「:/ ?」 例子: 1. 请在/tmp 这个目录下建立一个名为vitest 的目录: 2. 将/etc/man ...

  4. poorpool 的 考场 NOI Linux 配置

    把~/.bashrc里的force_color_prompt=yes前面那个#去掉,终端就有高亮啦qwq!(然后source一下 然后vim ~/.vimrc然后加入 (为什么不改/etc/vim/v ...

  5. redis入门:介绍、特点、安装、各类型常用操作

    一.redis介绍 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. Redis支持多种类型的数据结构,如 字符串(strings), 散列(ha ...

  6. springmvc基础篇—通过注解的方式去配置项目

    学习了通过xml方式去配置项目后,当然要掌握更简单更灵活的注解方式哟,这是官方推荐使用的方式. 一.修改配置文件,建议大家直接使用我的配置文件 <?xml version="1.0&q ...

  7. JQuery UI 日历加时间

    写一个面试时间通知.用jquery ui 具体功能已经可以了,不过样式还没调 一.需要引入的文件,这些可以到官网下载 <link rel="stylesheet" href= ...

  8. Nginx 配置 HTTPS自签名证书

    工具: OpenSSL ssl的开源实现,几乎实现了市面上所有的加密 libcrypto: 通用加密库, 任何软件要实现加密功能 链接调用这个库 libssl: TLS/SSL 加密库 openssl ...

  9. MySql数据库插入或更新报错:Cannot add or update a child row: a foreign key constraint fails

    具体报错信息: Cannot add or update a child row: a foreign key constraint fails (`xxx`.`AAA`, CONSTRAINT `t ...

  10. 【Python】Python内置函数dir详解

    1.命令介绍 最近学习并使用了一个python的内置函数dir,首先help一下: 复制代码代码如下: >>> help(dir)Help on built-in function ...