Bzoj2756 [SCOI2012]奇怪的游戏
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
1 2
2 3
3 3
1 2 3
2 3 4
4 3 2
Sample Output
-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]奇怪的游戏的更多相关文章
- bzoj2756: [SCOI2012]奇怪的游戏(网络流+分情况)
2756: [SCOI2012]奇怪的游戏 题目:传送门 题解: 发现做不出来的大难题一点一个网络流 %大佬 首先黑白染色(原来是套路...)染色之后就可以保证每次操作都一定会使黑白各一个各自的值加1 ...
- BZOJ2756:[SCOI2012]奇怪的游戏(最大流,二分)
Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...
- BZOJ2756 [SCOI2012]奇怪的游戏 【网络流 + 二分】
题目 Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 Blinker 想知 ...
- BZOJ2756 SCOI2012奇怪的游戏(二分答案+最大流)
由数据范围容易想到网络流.由于操作只是对于棋盘上相邻两格,容易想到给其黑白染色. 假设已经知道最后要变成什么数.那么给黑白点之间连边,其流量则表示同时增加的次数,再用源汇给其限流为需要增加的数即可. ...
- BZOJ2756 [SCOI2012]奇怪的游戏 最大流
好久没有写博客了.不过这个博客也没有多少人看 最近在写网络流,为了加深理解,来写一两篇题解. 对整个棋盘进行黑白染色以后可以发现,一次操作就是让二分图的两个点的值分别 \(+1\). 这样,我们就可以 ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3352 Solved: 919[Submit][Stat ...
- 【BZOJ-2756】奇怪的游戏 最大流 + 分类讨论 + 二分
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2925 Solved: 792[Submit][Stat ...
- [题目] 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 ...
随机推荐
- 15个nosql数据库
1.MongoDB 介绍 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.主要解决的是海量数据的访问效率问题,为WEB应用提供可扩展的高性能数据存储解决方案.当数据量达到50GB以上 ...
- C++变量命名规则
转自:http://www.cnblogs.com/finallyliuyu/archive/2010/09/25/1834301.html 浅谈C++变量命名规则 不知道别的公司如何,反正我现在的公 ...
- IE6 P标签下DIV无法inline-block
IE6 P标签下的DIV标签无法inline-block,使其触发了hasLayout属性再用csshack 使其inline还是不行,始终要换行 解决:把div标签替换成非div标签,比如span等 ...
- FineUI v3.3.1 发布了!
关于FineUI基于 ExtJS 的专业 ASP.NET 控件库. FineUI的使命创建 No JavaScript,No CSS,No UpdatePanel,No ViewState,No We ...
- Google Zxing 二维码生成与解析
生成二维码的开源项目可谓是琳琅满目,SwetakeQRCode.BarCode4j.Zxing...... 前端有JQuery-qrcode,同样能实现生成二维码. 选择Zxing的原因可能是对 Go ...
- lecture5-对象识别与卷积神经网络
Hinton第五课 突然不知道object recognition 该翻译成对象识别好,还是目标识别好,还是物体识别好,但是鉴于范围性,还是翻译成对象识别吧.这一课附带了两个论文<Convolu ...
- 十分钟掌握Activity的生命周期与启动模式
1. Activity的生命周期 正常情况下的Activity生命周期如下图所示(来自Android Developer): 当资源相关的系统配置变更时(比如设备屏幕方向改变,键盘可见性变化),会导致 ...
- 理解Android虚拟机体系结构
1 什么是Dalvik虚拟机 Dalvik是Google公司自己设计用于Android平台的Java虚拟机,它是Android平台的重要组成部分,支持dex格式(Dalvik Executable)的 ...
- Bootstrap系列 -- 7. 列表排版方式
一. 去点列表 1. 使用class=list-unstyled <ul > <li>无序列表项目</li> <li>无序列表项目</li> ...
- ModernUI教程:定义一个Logo
ModernWindow的标题栏包含了一块区域用来显示自定义的窗体Logo: 这个窗体logo通过ModernWindow.LogoData属性来设置.这个属性是几何类型数据支持Path.Data m ...