由数据范围容易想到网络流。由于操作只是对于棋盘上相邻两格,容易想到给其黑白染色。

  假设已经知道最后要变成什么数。那么给黑白点之间连边,其流量则表示同时增加的次数,再用源汇给其限流为需要增加的数即可。

  考虑最后应该变成什么数。

  如果棋盘中黑白格子数量不同,设最后变成的数是x,则x*黑格数量-黑格数字和=x*白格数量-白格数字和,若黑格数量多即x=黑格数字和-白格数字和。直接变为最大值是不一定合法的。

  否则首先黑白格子内权值和应相同,否则无解。如果变成某个数是合法的,变的更大也是合法的。那么二分最后变成的数即可。因为最终方案中并不一定存在能恰好覆盖整个棋盘的操作,所以直接变为最大数是错的。注意二分上界需要开的非常大。

  无数次死于long long。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 42
#define S 0
#define T 1601
#define inf 2000000000000
int test,n,m,p[N*N],a[N][N],t;
int d[N*N],q[N*N],cur[N*N];
bool flag[N*N];
long long ans;
struct data{int to,nxt;long long cap,flow;
}edge[N*N<<];
void addedge(int x,int y,long long z)
{
t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=,p[x]=t;
t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=,edge[t].flow=,p[y]=t;
}
int trans(int x,int y){return (x-)*m+y;}
bool bfs()
{
memset(d,,sizeof(d));d[S]=;
int head=,tail=;q[]=S;
do
{
int x=q[++head];
for (int i=p[x];~i;i=edge[i].nxt)
if (d[edge[i].to]==-&&edge[i].flow<edge[i].cap)
{
d[edge[i].to]=d[x]+;
q[++tail]=edge[i].to;
}
}while (head<tail);
return ~d[T];
}
long long work(int k,long long f)
{
if (k==T) return f;
long long used=;
for (int i=cur[k];~i;i=edge[i].nxt)
if (d[k]+==d[edge[i].to])
{
long long w=work(edge[i].to,min(edge[i].cap-edge[i].flow,f-used));
edge[i].flow+=w,edge[i^].flow-=w;
if (edge[i].flow<edge[i].cap) cur[k]=i;
used+=w;if (used==f) return f;
}
if (used==) d[k]=-;
return used;
}
void dinic()
{
ans=;
while (bfs())
{
memcpy(cur,p,sizeof(p));
ans+=work(S,inf);
}
}
bool check(long long k,long long lim)
{
t=-;memset(p,,sizeof(p));
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (i+j&)
{
addedge(S,trans(i,j),k-a[i][j]);
if (i>) addedge(trans(i,j),trans(i-,j),inf);
if (i<n) addedge(trans(i,j),trans(i+,j),inf);
if (j>) addedge(trans(i,j),trans(i,j-),inf);
if (j<m) addedge(trans(i,j),trans(i,j+),inf);
}
else addedge(trans(i,j),T,k-a[i][j]);
dinic();
return ans==lim;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj2756.in","r",stdin);
freopen("bzoj2756.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
test=read();
while (test--)
{
n=read(),m=read();int v=;
long long sumx=,sumy=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
v=max(v,a[i][j]=read());
if (i+j&) sumx+=a[i][j];
else sumy+=a[i][j];
}
long long tot=-;
if ((n&)&&(m&)) tot=sumy-sumx>=v?(check(sumy-sumx,(sumy-sumx)*n*m-sumx-sumy>>)?sumy-sumx:-):-;
else
{
if (sumx==sumy)
{
long long l=v,r=inf;
while (l<=r)
{
long long mid=l+r>>;
if (check(mid,mid*n*m-sumx-sumy>>)) tot=mid,r=mid-;
else l=mid+;
}
}
}
if (tot==-) cout<<-<<endl;
else cout<<(tot*n*m-sumx-sumy>>)<<endl;
}
return ;
}

BZOJ2756 SCOI2012奇怪的游戏(二分答案+最大流)的更多相关文章

  1. Bzoj2756 [SCOI2012]奇怪的游戏

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 20155207 EXP8 Web基础

    20155207 EXP8 Web基础 实验内容 (1)Web前端HTML (2)Web前端javascipt (3)Web后端:MySQL基础:正常安装.启动MySQL,建库.创建用户.修改密码.建 ...

  2. 基于spring的redisTemplate的缓存工具类

    pom.xml文件添加 <!-- config redis data and client jar --><dependency> <groupId>org.spr ...

  3. 你应该知道Go语言的几个优势

    要说起GO语言的优势,我们就得从GO语言的历史讲起了-- 本文由腾讯技术工程官方号发表在腾讯云+社区 2007年,受够了C++煎熬的Google首席软件工程师Rob Pike纠集Robert Grie ...

  4. effective c++ 笔记 (35-40)

    //---------------------------15/04/24---------------------------- //#35   考虑virtual函数以外的其他选择 { /* 1: ...

  5. effective c++ 笔记 (23-25)

    //---------------------------15/04/08---------------------------- //#23   宁以non_member.non_friend替换m ...

  6. 如何安装ipa文件(二)

    第一篇文章请看: http://www.cnblogs.com/BK-12345/p/6000124.html 写第二篇的目的是因为iTunes更新了,有一些东西发生了变化,应用没有了,其实还是存在的 ...

  7. 机器学习英雄访谈录之 Kaggle Kernels 专家:Aakash Nain

    目录 机器学习英雄访谈录之 Kaggle Kernels 专家:Aakash Nain 正文 对我的启发 机器学习英雄访谈录之 Kaggle Kernels 专家:Aakash Nain Sanyam ...

  8. OpenMPI源码剖析:网络通信原理(二) 如何选择网络协议?

    因为比较常用的是 TCP 协议,所以在 opal/mca/btl/tcp/btl_tcp.h 头文件中找到对应的 struct mca_btl_tcp_component_t { mca_btl_ba ...

  9. 企业落地Kubernetes的问题与对策

    在当今云计算领域,“容器技术”已经从三四年前的炒作期正式进入了产业落地期,而Kubernetes作为容器平台的标准已经得到了广泛应用. Kubernetes从2014年6月由Google宣布开源,到2 ...

  10. 《Linux内核分析》 第二节 操作系统是如何工作的

    Linux内核分析 第二周 操作系统是如何工作的 张嘉琪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/UST ...