题目链接

\(Description\)

\(Solution\)

这种题当然要黑白染色。。

两种颜色的格子数可能相同,也可能差1。记\(n1/n2\)为黑/白格子数,\(s1/s2\)为黑/白格子权值和。

如果\(n1\neq n2\),假设\(n1>n2\),因为每次是同时给两种颜色+1,所以最后的差也只能是\(s1-s2\)(\(s1>s2\)),个数只差1,所以也只能都变成\(s1-s2\)。(注意\(s1-s2\geq A_{max}\))

如果\(n1=n2\),假设\(x\)合法,那么\(x+1\)也合法,因为黑白可以两两配对并加一。

即可以二分答案。

二分图匹配模型,二分后边的容量就可以确定了。最大流是\((x*tot-s1-s2)/2\)或者源点汇点都满流则合法。

那个。。上限是\(A_{max}\)么。。显然不是啊。

忍不住吐槽,这写的有点。。

//1284kb	5160ms
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 150000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1700,M=N<<3;
const LL INF=1e14; int n,m,src,des,A[N],Enum,H[N],cur[N],nxt[M],fr[M],to[M],pre[N],lev[N],num[N];
LL cap[M];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}//我可能有毒
#define AddEdge(u,v,w) to[++Enum]=v,fr[Enum]=u,nxt[Enum]=H[u],H[u]=Enum,cap[Enum]=w,to[++Enum]=u,fr[Enum]=v,nxt[Enum]=H[v],H[v]=Enum,cap[Enum]=0
bool BFS()
{
static int q[N];
for(int i=src; i<des; ++i) lev[i]=des+1;
lev[des]=0, q[0]=des; int h=0,t=1;
while(h<t)
{
int x=q[h++];
for(int i=H[x]; i; i=nxt[i])
if(cap[i^1] && lev[to[i]]==des+1) lev[to[i]]=lev[x]+1, q[t++]=to[i];
}
return lev[src]<=des;
}
inline LL Augment()
{
LL mn=INF;
for(int i=des; i!=src; i=fr[pre[i]])
mn=std::min(mn,cap[pre[i]]);
for(int i=des; i!=src; i=fr[pre[i]])
cap[pre[i]]-=mn, cap[pre[i]^1]+=mn;
return mn;
}
LL ISAP()
{
if(!BFS()) return 0ll;
for(int i=src; i<=des; ++i) ++num[lev[i]],cur[i]=H[i];
int x=src; LL res=0;
while(lev[src]<=des)
{
if(x==des) x=src, res+=Augment();
bool can=0;
for(int i=cur[x]; i; i=nxt[i])
if(lev[to[i]]==lev[x]-1 && cap[i])
{
can=1, cur[x]=i, pre[x=to[i]]=i;
break;
}
if(!can)
{
int mn=des;
for(int i=H[x]; i; i=nxt[i])
if(cap[i]) mn=std::min(mn,lev[to[i]]);
if(!--num[lev[x]]) break;
++num[lev[x]=mn+1], cur[x]=H[x];
if(x!=src) x=fr[pre[x]];
}
}
return res;
}
bool Check(LL x,LL s1,LL s2)
{
Enum=1, memset(H,0,sizeof H);
int tot=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
{
++tot;
if((i+j)&1)
{
AddEdge(src,tot,x-A[tot]);//, sum+=x-A[tot];
if(i<n) AddEdge(tot,tot+m,INF);//边是有向的,不能容量都为INF啊mdzz
if(j<m) AddEdge(tot,tot+1,INF);
}
else
{
AddEdge(tot,des,x-A[tot]);
if(i<n) AddEdge(tot+m,tot,INF);//white->black!
if(j<m) AddEdge(tot+1,tot,INF);
}
}
return (ISAP()<<1ll)==(x*tot-s1-s2);//ISAP()==sum;
} int main()
{
for(int T=read(); T--; )
{
n=read(), m=read(), src=0, des=n*m+1;
int tot=0,mx=0; LL s1=0,s2=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
mx=std::max(mx,A[++tot]=read()),(i+j)&1?(s2+=A[tot]):(s1+=A[tot]);//s1,s2别反。。
if(tot&1) printf("%lld\n",(/*s1>s2&&*/s1-s2>=mx&&Check(s1-s2,s1,s2))?(((s1-s2)*tot-s1-s2)>>1ll):-1ll);
else if(s1!=s2) puts("-1");
else
{
LL l=mx,r=INF,mid;
while(l<r)
{
if(Check(mid=l+r>>1,s1,s2)) r=mid;
else l=mid+1;
}
printf("%lld\n",l<INF?(1ll*(tot>>1)*l-s1/*(1ll*tot*l-s1-s2)>>1ll*/):-1ll);
}
}
return 0;
}

BZOJ.2756.[SCOI2012]奇怪的游戏(二分 黑白染色 最大流ISAP)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

    这道题提醒我,要有将棋盘黑白染色的意识,尤其是看到相邻格子这样的条件的时候,然后就是要用到与其有关的性质与特点以体现其作用,这道题就是用到了黑格子与白格子之间的关系进行的,其出发点是每次一定会给一个黑 ...

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

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

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

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

随机推荐

  1. Dubbo本地存根

    在远程调用服务提供者的实现之前,如果需要做一些参数验证.缓存.判断.小功能等等,满足要求再调用服务提供者的远程服务,则我们可以通过编写一个本地存根来实现这种功能. (1).在公共项目中或服务消费者项目 ...

  2. GCC编译过程与动态链接库和静态链接库

    1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...

  3. Linux input子系统简介

    1.前言 本文主要对Linux下的input子系统进行介绍 2. 软件架构 图 input子系统结构图 input子系统主要包括三个部分:设备驱动层.核心层和事件层.我们可以分别理解为:具体的输入设备 ...

  4. openstack swift节点安装手册3-最后的安装配置及验证

    以下步骤都在controller节点上执行 1.远程获取/etc/swift/swift.conf文件: curl -o /etc/swift/swift.conf https://git.opens ...

  5. 为什么在python中推荐使用多进程而不是多线程(转载)

    最近在看Python的多线程,经常我们会听到老手说:"Python下多线程是鸡肋,推荐使用多进程!",但是为什么这么说呢? 要知其然,更要知其所以然.所以有了下面的深入研究: GI ...

  6. 【linux】centos6.9安装gearman

    1.确认yum源没问题,如果有问题,参照这里更换 2. yum install -y boost-devel gperf libevent-devel libuuid-devel yum instal ...

  7. C#中的预处理指令详解

    这篇文章主要介绍了C#中的预处理指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregion ...

  8. 浅谈Phoenix在HBase中的应用

    一.前言 业务使用HBase已经有一段时间了,期间也反馈了很多问题,其中反馈最多的是HBase是否支持SQL查询和二级索引,由于HBase在这两块上目前暂不支持,导致业务在使用时无法更好的利用现有的经 ...

  9. Maven多模块项目

    1.项目结构-父项目 其中parent是父项目,这个父项目的父项目是springboot,我搭建这个多模块的项目的目的主要是为了研究学习springbatch 父项目的pom文件内容: <pro ...

  10. CSS3实现整屏切换效果

    页面结构 实现思路与大众方法类似,如图 每个section就是一页内容,它的大小充满了屏幕(红色区域),一个Container由多个section构成,我们通过改变container的位置,来达到页面 ...