达成成就:为二分调参

!:多次memset的话要把数组大小开严格一点,否则会T

看到网格图,首先黑白染色。

注意到每次操作都是在一个黑格子和一个白格子上进行的,也就是说,最后黑格子数字和白格子数字和的差是不变的。

对于n*m%2==0的情况:

  • 注意到在这种情况下黑格子和白格子一样多,也就是当黑格子数字和和白格子数字和不相等时,一定是不合法状态,反之一定合法。
  • 那么二分最小的最终数字

对于于n*m%2==1情况:

  • 注意到在这种情况下两种格子的数量差1,也就是说格子个数较多的一种格子的数字和与另一种格子的数字和之差就是最终数字。不合法状态之一即为数字之差比初始状态中数字最大的格子中的数字小。
  • 那么判断是否合法

判断方法:

  • 建立流量网络,s连向所有黑格子,所有白格子连向t,流量均为当前格子的值与最终数字之差,所有黑格子向与他相邻的白格子连流量为inf的边(黑白格子反过来也可以)
  • 跑最大流,看是否全部满流,即可以通过一些方案使所有格子达到最终数字
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const long long N=55,P=25005,inf=1e11;
long long T,n,m,a[N][N],col[N][N],sum,le[P],cnt,h[P],s,t,mn,c0,c1,s0,s1;
struct qwe
{
long long ne,to,va;
}e[P<<1];
long long read()
{
long long r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void add(long long u,long long v,long long w)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
e[cnt].va=w;
h[u]=cnt;
}
void ins(long long u,long long v,long long w)
{// cout<<u<<" "<<v<<" "<<w<<endl;
add(u,v,w);
add(v,u,0);
}
bool bfs()
{
memset(le,0,sizeof(le));
queue<long long>q;
le[s]=1;
q.push(s);
while(!q.empty())
{
long long u=q.front();
q.pop();
for(int i=h[u];i;i=e[i].ne)
if(e[i].va>0&&!le[e[i].to])
{
le[e[i].to]=le[u]+1;
q.push(e[i].to);
}
}
return le[t];
}
long long dfs(long long u,long long f)
{
if(u==t||!f)
return f;
long long us=0;
for(int i=h[u];i&&us<f;i=e[i].ne)
if(e[i].va>0&&le[e[i].to]==le[u]+1)
{
long long t=dfs(e[i].to,min(e[i].va,f-us));
e[i].va-=t;
e[i^1].va+=t;
us+=t;
}
if(!us)
le[u]=0;
return us;
}
long long dinic()
{
long long re=0;
while(bfs())
re+=dfs(s,inf);
return re;
}
bool ok(long long c)
{
memset(h,0,sizeof(h));
long long sum=0ll;
cnt=1;s=0,t=n*m+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
long long x=(i-1)*m+j;
if(col[i][j])
{
ins(s,x,c-a[i][j]),sum+=c-a[i][j];
if(i!=1)
ins(x,(i-2)*m+j,inf);
if(i!=n)
ins(x,i*m+j,inf);
if(j!=1)
ins(x,(i-1)*m+j-1,inf);
if(j!=m)
ins(x,(i-1)*m+j+1,inf);
}
else
ins(x,t,c-a[i][j]);
}
return dinic()==sum;
}
int main()
{
T=read();
while(T--)
{
c0=c1=s0=s1=mn=0;
n=read(),m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
a[i][j]=read();
col[i][j]=(i+j)&1;
mn=max(mn,a[i][j]);
if(col[i][j])
s1+=a[i][j],c1++;
else
s0+=a[i][j],c0++;
}
if(c0!=c1)
{
long long x=(s0-s1)/1;
if(x>mn&&ok(x))
printf("%lld\n",x*c1-s1);
else
puts("-1");
}
else
{
if(s0!=s1)
{
puts("-1");
continue;
}
long long l=mn,r=inf;
while(l<=r)
{
long long mid=(l+r)>>1;
if(ok(mid))
r=mid-1;
else
l=mid+1;
}
printf("%lld\n",l*c1-s1);
}
}
return 0;
}

bzoj 2756 [SCOI2012]奇怪的游戏【二分+最大流】的更多相关文章

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

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

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

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

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

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

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

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

  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. linux 常见名词及命令(二)

    pwd 用于显示当前的工作目录. cd 用于切换工作路径 cd - 切换到上一次的目录 cd ~ 切换到家目录 cd ~username 切换到其他用户的家目录 cd .. 切换到上级目录 ls 用于 ...

  2. hashlib-sha摘要算法模块

    摘要:hashlib: 摘要算法的模块 用处: 1.查看某两个文件是否完全一致 "abcdefggg" "abcdefhhg" 2.加密认证 把密码加密后写入文 ...

  3. hdu 3943

    数位dp #include <cstdio> #include <cstdlib> #include <cmath> #include <stack> ...

  4. spring-security 理解 笔记 介绍以及使用(持续更新)

    本人经过2周的学习,成功搭建了认证服务器,资源服务器和客户端 .下面是本人对 oauth2的理解,以及spring-security的使用,如果理解错误的地方,还望指正. 现在代码有点凌乱,过段时间会 ...

  5. Extjs.panel.Panel赋值的问题

    初学extjs,很是不爽.也是只有初学者才犯的错误,发出来以免再犯. 先创建一个panel var panel1 = Ext.create('Ext.panel.Panel', { id: 'p1', ...

  6. Java后端技术书单

    写博客记录技术上使用的各种问题,这个只能算是一个打游击. 如果要把一个知识学透,最有效的方式就是系统学习,而系统学习就是看书,书本上有清晰的学习路线以及相应的技术栈. 下面是我收集的Java后端的技术 ...

  7. oracle 用户账户被锁处理

    一.以管理员身份登录 SQL> conn sys/sys as sysdba; (分号是必须的但是我是以system登录的所在这不应该写conn sys/sys as sysdba应该写conn ...

  8. 【网络】TCP的流量控制

    一.利用滑动窗口实现流量控制 流量控制是让发送方的发生速率不要太快,要让接收方来得及接收. 发送方的发送窗口不能超过接收方给出的接收窗口的数值,TCP的窗口单位是字节,不是报文段. TCP为每一个连接 ...

  9. 笔记本 ThinkPad E40 安装 Mac OS X 10.9.3 Mavericks 系统

    关于:自己最早接触Mac OS X系统是在一个论坛里.记得好像是2011年:那时论坛里就有人在虚拟机上执行Mac OS X 10.7系统.当时也依照论坛里的方法在虚拟机上成功装上了系统.那时開始就被苹 ...

  10. 使用JS对select标签进行联动选择

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...