2756: [SCOI2012]奇怪的游戏

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 3220  Solved: 886

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

最大流。

对原图进行二分图染色,统计黑白格子的个数和各自的数量和。

每次加值,肯定是黑白格子各+1

设最终数值为D,得到:

  D*cntW-sumW == D*cntB - sumB

如果格子数为奇数,也就是黑白格子不等,D是唯一的,只需要建立流量网络验证是否可行即可。

如果格子数为偶数: 如果sum不等,无解,否则可以二分D,验证是否可行并记录答案。

建图方法:

  S到白格子连边,容量为D-格子权值

  白格子到四周黑格子连边,容量为INF

  黑格子到T连边,容量为D-格子权值

_____________

然后就愉快地WA了一串,调了好久好久。在那么一个瞬间察觉到哪里不对,再一看代码……我的init函数放在了二分前面,处理奇数情况时好像没调用?

23333翻出了第一次提交的记录,代码复制出来,换了init的位置,AC

233333这好像是第三次没有初始化了,第一次是某次写LCA,第二次是网络流

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define LL long long
using namespace std;
const int mx[]={,,,-,};
const int my[]={,,,,-};
const int mxn=;
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;
}
struct edge{int v,nxt;LL f;}e[mxn<<];
int hd[mxn],mct=;
void add_edge(int u,int v,LL f){
e[++mct].v=v;e[mct].f=f;e[mct].nxt=hd[u];hd[u]=mct;return;
}
void ins(int u,int v,LL f){add_edge(u,v,f);add_edge(v,u,);return;}
int n,m,S,T;
int mp[][];
int id[][];
int d[mxn];
bool BFS(){
memset(d,,sizeof d);
queue<int>q;
d[S]=;
q.push(S);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(!d[v] && e[i].f){
d[v]=d[u]+;
q.push(v);
}
}
}
return d[T];
}
LL DFS(int u,LL lim){
if(u==T)return lim;
LL tmp,f=;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(d[v]==d[u]+ && e[i].f){
tmp=DFS(v,min(lim,e[i].f));
e[i].f-=tmp;
e[i^].f+=tmp;
lim-=tmp;
f+=tmp;
if(!lim)return f;
}
}
d[u]=;
return f;
}
LL Dinic(){
LL res=;
while(BFS())res+=DFS(S,1e16);
return res;
}
void init(){
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
id[i][j]=(i-)*m+j;
return;
}
LL ans=;
bool solve(LL lim){
memset(hd,,sizeof hd);
mct=;
int i,j;
LL tar=;
for(i=;i<=n;i++)
for(j=;j<=m;j++){
if((i+j)%==){
ins(S,id[i][j],lim-mp[i][j]);
tar+=lim-mp[i][j];
for(int k=;k<=;k++){
int nx=i+mx[k];
int ny=j+my[k];
if(nx> && nx<=n && ny> && ny<=m){
ins(id[i][j],id[nx][ny],1e16);
}
}
}
else{ins(id[i][j],T,lim-mp[i][j]);}
}
if(Dinic()==tar){
ans=tar;
return ;
}
return ;
}
int main()
{
int Cas=read();
int i,j;
while(Cas--){
int mxnum=-1e9;
n=read();m=read();
for(i=;i<=n;i++)
for(j=;j<=m;j++){
mp[i][j]=read();
mxnum=max(mxnum,mp[i][j]);
}
S=;T=n*m+;
init();
LL numw=,numb=,cntw=,cntb=;
for(i=;i<=n;i++)
for(j=;j<=m;j++){
if((i+j)%==){
numw+=mp[i][j];cntw++;
}
else{
numb+=mp[i][j];cntb++;
}
}
if(n*m%==){ LL D=(numw-numb)/(cntw-cntb);
if(D>=mxnum && solve(D)){printf("%lld\n",ans);}
else printf("-1\n");
continue;
}
else{
if(numb!=numw){
printf("-1\n");
continue;
}
ans=-;
LL l=mxnum,r=1e16;
while(l<=r){
LL mid=(l+r)>>;
if(solve(mid)){
r=mid-;
}
else l=mid+;
}
printf("%lld\n",ans);
}
}
return ;
}

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

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

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

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

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

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

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

  4. BZOJ2756 SCOI2012奇怪的游戏(二分答案+最大流)

    由数据范围容易想到网络流.由于操作只是对于棋盘上相邻两格,容易想到给其黑白染色. 假设已经知道最后要变成什么数.那么给黑白点之间连边,其流量则表示同时增加的次数,再用源汇给其限流为需要增加的数即可. ...

  5. BZOJ2756 [SCOI2012]奇怪的游戏 最大流

    好久没有写博客了.不过这个博客也没有多少人看 最近在写网络流,为了加深理解,来写一两篇题解. 对整个棋盘进行黑白染色以后可以发现,一次操作就是让二分图的两个点的值分别 \(+1\). 这样,我们就可以 ...

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

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

  7. 【BZOJ-2756】奇怪的游戏 最大流 + 分类讨论 + 二分

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

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

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

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

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

随机推荐

  1. Post model至Web Api创建或是保存数据

    前一篇<Post model至Web Api>http://www.cnblogs.com/insus/p/4343538.html中,使用Post来从Web Api获取数据.由于Post ...

  2. CentOS VMware 下SSH配置方法详解

    1.安装SSH[root@sample ~]# yum install ssh2.启动SSH[root@sample ~]# service sshd start3.设置开机运行[root@sampl ...

  3. QT TCP文件上传服务器

    利用QT做为client端,纯C语言做为server端,利用tcp协议,实现client端向server端传递文件 Linux服务器端 //头文件 #include <stdio.h> # ...

  4. C#执行XSL转换

    xsl 可方便的将一种格式的xml,转换成另一种格式的xml,参考下面的代码: using System; using System.IO; using System.Text; using Syst ...

  5. WebPack系列:Webpack编译的代码如何在tomcat中使用时静态资源路径不对的问题如何解决

    问题:     使用webpack+vue做前端,使用tomcat提供api,然后npm run build之后需要将编译,生成如下文件: |   index.html \---appserver   ...

  6. logstash搭建日志追踪系统

    前言 开始博客之前,首先说下10月份没写博客的原因 = =. 10月份赶上国庆,回了趟老家休息了下,回来后自己工作内容发生了点改变,开始搞一些小架构的东西以及研究一些新鲜东西,当时我听到这个消息真的是 ...

  7. 网页中三角切边还半透明,现在的设计师越来越牛,css也要跟上啊

    需求 今天在群里看到一个需求,啊这种三角形缺角怎么做啊,还带半透明阴影的. 分析 要实现这个,可以用css做三角,网上找一下代码,像这样. 由于以前没有试过border能不能带透明,所以需要试验一下. ...

  8. C#中数组Array、ArrayList、泛型List<T>的比较

    在C#中数组Array,ArrayList,泛型List都能够存储一组对象,但是在开发中根本不知道用哪个性能最高,下面我们慢慢分析分析. 一.数组Array 数组是一个存储相同类型元素的固定大小的顺序 ...

  9. Chrome 监听 console 打开

    这个算是 Chrome only 其他的我没测试,也不想测试.因为我的控制台脚本仅仅在 Chrome 下加载. 如果你需要全平台,那么这肯定不是你需要的结果. 需求 其实我很早就想折腾这个了,但是,, ...

  10. jQuery学习笔记(四):attr()与prop()的区别

    这一节针对attr()与prop()之间的区别进行学习. 先看看官方文档是如何解释两者之间功能差异的: attr() Get the value of an attribute for the fir ...