Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 4403  Solved: 1226
[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

【题解】

         ①你有一个很好的愿望:要是能知道最后的棋盘是什么样子就好了!

         ②设棋盘最后都为x(同时和数与形状相关的问题,染色很实用),

           染色后设白格总数num1,和sum1;黑格总数num2,和sum2;我们可以写下这样的式子:
           x*num1-sum1=x*num2-
sum2 (由于选取相邻的两个格+1) 化一化:
           sum1-sum2=x*(num1-num2) 回到初中学过的一元一次方程解的讨论:
           若num1-num2≠0 ,解出x,若比原图中maxn还小,就一定不行,反之check一下;

           若num1-num2=0,若sum1-sum2≠0肯定就没戏了,反之就此方程对应了很多很多解,考虑实际情况我们可以说在这种情况下:x取a成立的话,取a+1一定成立(但是对a和a-1就不一定对了,我就是错在这里的),二分+check即可;

③check的话就超源连白色,超汇连黑色,边为差值,对白格向相邻黑格建inf边,看是否满流。

 

 /*2
2 2
1 2
2 3
3 3
1 2 3
2 3 4
4 3 2
没去freopen居然调了半个小时,醉了。
inf和INF什么的,最讨厌了。
染色技巧很玄妙!
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <ctime>
#include <cmath>
#define ll long long
#define N 50
#define mem(f,a) memset(f,a,sizeof(f))
#define Run(i,l,r) for(ll i=l;i<=r;i++)
#define Don(i,l,r) for(ll i=l;i>=r;i--)
#define Eun(i,u,E,head) for(ll i=head[u],v=E[i].v;i!=-1;i=E[i].next,v=E[i].v)
using namespace std;
int n,m;
const ll inf=(1LL<<);
const ll INF=(1LL<<);
struct Edge{
int v,next;
ll cap,flow;
}E[];
ll a[N][N],color[N][N];
ll head[N*N],k,cur[N*N],vis[N*N],d[N*N];
int dx[]={,,,-},dy[]={,-,,};
queue<int>q;
int idx(int i,int j){return (i-)*m+j;}
void adde(int u,int v,ll cap)
{ E[k]=(Edge){v,head[u],cap,};
head[u]=k++;
E[k]=(Edge){u,head[v],,};
head[v]=k++;
}
bool Bfs()
{ mem(vis,); mem(d,);
vis[]=; q.push();
while (!q.empty()){
int u=q.front(); q.pop();
Eun(i,u,E,head)if (E[i].cap>E[i].flow&&!vis[v]){
vis[v]=;
q.push(v);
d[v]=d[u]+;
}
}
return (vis[n*m+]);
}
ll Dfs(int u,ll a)
{ if (u==n*m+||a==) return a;
ll flow=,f;
Eun(i,u,E,cur){
cur[u]=i;
if (d[v]==d[u]+&&(f=Dfs(v,min(E[i].cap-E[i].flow,a)))>){
flow+=f;
a-=f;
E[i].flow+=f;
E[i^].flow-=f;
}
if (a==) break;
}
return flow;
}
ll Dinic()
{ ll flow=;
while (Bfs()){
Run(i,,n*m+) cur[i]=head[i];
flow+=Dfs(,INF);
}
return flow;
}
bool check(ll x)
{ k=; mem(head,-);
ll tot=;
Run(i,,n)
Run(j,,m){
if (color[i][j]) {
tot+=x-a[i][j];
adde(,idx(i,j),x-a[i][j]);
Run(k,,){
int ni=i+dx[k]; int nj=j+dy[k];
if (ni>&&nj>&&ni<=n&&nj<=m) adde(idx(i,j),idx(ni,nj),INF);
}
}
else adde(idx(i,j),n*m+,x-a[i][j]);
}
if (tot==Dinic()) return ;
else return ;
}
int main()
{ freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
int T;
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
ll maxn=,num1=,num2=; ll sum1=,sum2=;
Run(i,,n)
Run(j,,m){
scanf("%lld",&a[i][j]);
maxn=max(maxn,a[i][j]);
if ((i+j)&) color[i][j]=,sum1+=a[i][j],num1++;
else color[i][j]=,sum2+=a[i][j],num2++;
}
if (num1==num2) {
if (sum1!=sum2) {printf("-1\n"); continue;}
ll l=maxn,r=inf,x=;
while (l<r){
ll mid=(l+r)/;
if (check(mid)) x=mid,r=mid;
else l=mid+;
}
if (x) printf("%lld\n",1ll*x*num1-sum1);
else printf("-1\n");
}
else {
ll temp=(sum1-sum2)/(num1-num2);
if (temp>=maxn&&check(temp)) printf("%lld\n",1ll*temp*num1-sum1);
else printf("-1\n");
}
}
return ;
}//by tkys_Austin;

【bzoj2756 奇怪的游戏】的更多相关文章

  1. BZOJ-2756 奇怪的游戏 黑白染色+最大流+当前弧优化+二分判断+分类讨论

    这个题的数据,太卡了,TLE了两晚上,各种调试优化,各种蛋疼. 2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MB Submit ...

  2. [bzoj2756]奇怪的游戏

    对棋盘黑白染色后,若n和m都是奇数(即白色和黑色点数不同),可以直接算得答案(根据白-黑不变):若n和m不都是奇数,二分答案(二分的上限要大一点,开$2^50$),最后都要用用网络流来判定.考虑判定, ...

  3. 【BZOJ2756】奇怪的游戏(二分,最小割)

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

  4. 【BZOJ2756】奇怪的游戏(二分,网络流)

    [BZOJ2756]奇怪的游戏(二分,网络流) 题面 BZOJ Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blink ...

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

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

  6. Bzoj2756 [SCOI2012]奇怪的游戏

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

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

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

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

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

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

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

随机推荐

  1. 21.1 XMLHttpRequest 对象【JavaScript高级程序设计第三版】

    IE5 是第一款引入XHR 对象的浏览器.在IE5 中,XHR 对象是通过MSXML 库中的一个ActiveX对象实现的.因此,在IE 中可能会遇到三种不同版本的XHR 对象,即MSXML2.XMLH ...

  2. C语言程序设计·谭浩强(第四版)第二章课后习题的答案,算法——程序的灵魂

    C语言程序小练习 1.用C语言设计程序算出1-1/2+1/3-14+1/5...+1/99-1/100的值 #include<stdio.h> int main() { ; double ...

  3. kuangbin 最小生成树

    A & M - Jungle Roads HDU - 1301 题意:字母之间的路,求最小生成树 题解:处理好建边以后就是一个Prime #include<cstdio> #inc ...

  4. Intellij 出现“Usage of API documented as @since 1.4+”的解决办法

    https://blog.csdn.net/wust_lh/article/details/73277185

  5. shell重温---基础篇(函数操作)

        linux shell 可以用户定义函数,然后在shell脚本中可以随便调用.shell中函数的定义格式如下: [ function ] funname [()] { action; [ret ...

  6. @Transactional spring 事务失效(转载)

    原文地址:http://hwak.iteye.com/blog/1611970 1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和 ...

  7. 20145202马超《JAVA》预备作业1

    20145202马超<JAVA>预备作业1 你觉得自己专业吗?对专业的期望是什么? 我觉得自己很不专业,我对专业的期望:老师之前讲过德国的一个研究,学习分为5个档次,第三个档是能够自己发现 ...

  8. java冒泡算法

    public static void maopao() { int temp; int[] values = {2, 34, 0, 245}; for (int i = 0; i < value ...

  9. jmeter动态获取jsessionid

    思想是在一个线程组内添加一个cookie管理器,登录之后,用正则提取到sessionid,该线程组下的操作便可以共享这个session了. 1. 依次新建线程组.cookie管理器.http请求-登录 ...

  10. 名字管理系统demo

    # 名字管理系统demo # 打印功能提示 print('欢迎使用名字管理系统v6.6.6') print('1:添加一个名字') print('2:删除一个名字') print('3:修改一个名字' ...