题目链接

题意分析

首先我们需要求的是统一以后的值\(x\)

并且一般的棋盘操作我们都需要黑白染色

那么对于棋盘格子是偶数的情况的话

答案是存在单调性的

因为如果统一之后 两两搭配还是可以再加一个的

如果棋盘格子是奇数的话

那么黑格子数量为\(num1\) 权值和为\(sum1\)

白格子数量为\(num2\) 权值和为\(sum2\)

那么

\[num1*x-sum1=num2*x-sum2
\]

然后我们可以使用最大流检验合法性

用源点向黑色的点连边权为\(x-num[i][j]\)的边

白色的点向汇点连边权为\(x-num[i][j]\)的边

然后黑色的点向白色的点连边权为\(inf\)的边

然后检查能否跑满流即可

至于这么做的意义 应该很好理解

也就是相邻两个点之间的匹配问题

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>
#define ll long long
#define inf 1e18
#define N 48
#define IL inline
#define M 1008611
#define D double
#define ull unsigned long long
#define R register
using namespace std;
template<typename T>IL void read(T &_)
{
T __=0,___=1;char ____=getchar();
while(!isdigit(____)) {if(____=='-') ___=0;____=getchar();}
while(isdigit(____)) {__=(__<<1)+(__<<3)+____-'0';____=getchar();}
_=___ ? __:-__;
}
/*-------------OI使我快乐-------------*/
ll opt,n,m,tot=1,S,T,maxn;
ll sum1,sum2,num1,num2,all;
ll hei[N][N],bel[N][N];
ll to[M],nex[M],head[N*N],fro[M];ll w[M];
ll dep[N*N],cur[N*N];queue<ll> Q;
ll tx[6]={0,0,0,1,-1},ty[6]={0,1,-1,0,0};
IL void add(ll x,ll y,ll z)
{to[++tot]=y;fro[tot]=x;nex[tot]=head[x];head[x]=tot;w[tot]=z;
swap(x,y);to[++tot]=y;fro[tot]=x;nex[tot]=head[x];head[x]=tot;w[tot]=0;}
IL bool safe(ll x,ll y){return x>=1&&x<=n&&y>=1&&y<=m;}
IL ll id(ll x,ll y){return (x-1)*m+y;}
IL bool bfs()
{
for(R ll i=1;i<=T;++i) dep[i]=0;
Q.push(S);dep[S]=1;
for(;!Q.empty();)
{
ll u=Q.front();Q.pop();
for(R ll i=head[u];i;i=nex[i])
{
ll v=to[i];
if(w[i]>0&&dep[v]==0)
{
dep[v]=dep[u]+1;Q.push(v);
}
}
}
return dep[T]!=0;
}
IL ll dfs(ll now,ll res)
{
if(now==T||!res) return res;
for(R ll &i=cur[now];i;i=nex[i])
{
ll v=to[i];
if(w[i]>0&&dep[v]==dep[now]+1)
{
ll have=dfs(v,min(w[i],res));
if(have>0)
{
w[i]-=have;w[i^1]+=have;
return have;
}
}
}
return 0;
}
IL void Dinic()
{
while(bfs())
{
// printf("now nowno\n");
for(R ll i=1;i<=T;++i) cur[i]=head[i];
ll d=dfs(S,inf);
// printf("now now now %lld\n",d);
while(d) all+=d,d=dfs(S,inf);
}
}
IL bool check(ll now)
{
tot=1;all=0;ll tmp=0;
memset(head,0,sizeof head);
for(R ll i=1;i<=n;++i)
for(R ll j=1;j<=m;++j)
if((i+j)&1) add(S,id(i,j),now-hei[i][j]),tmp+=(now-hei[i][j]);
else add(id(i,j),T,now-hei[i][j]);
for(R ll i=1;i<=n;++i)
for(R ll j=1;j<=m;++j)
if((i+j)&1)
for(R ll k=1;k<=4;++k)
{ ll nowx=i+tx[k],nowy=j+ty[k];
if(safe(nowx,nowy)) add(id(i,j),id(nowx,nowy),inf);
}
// printf("now is %lld but need is %lld\n",all,tmp);
Dinic();
// printf("now is %lld but need is %lld\n",all,tmp);
return (all==tmp);
}
IL void solve_cdy()
{
ll le=maxn,ri=1e15,ans=-1;
while(le<=ri)
{
// printf("%lld %lld\n",le,ri);
ll mid=(le+ri)>>1;
if(check(mid)) ans=mid,ri=mid-1;
else le=mid+1;
}
// printf("%d\n",ans);
if(ans==-1) puts("-1");
else printf("%lld\n",(ans*num1)-sum1);
}
IL void solve_wzy()
{
if((sum1-sum2)%(num1-num2)==0)
{
ll tox=(sum1-sum2)/(num1-num2);
// printf("tox si %d\n",tox);
if(tox<1ll*maxn) {puts("-1");return;}
if(check(tox)) printf("%lld\n",(tox*num1)-sum1);
else puts("-1");
}
else puts("-1");
}
int main()
{
// freopen("222.in","r",stdin);
// freopen("222.out","w",stdout);
read(opt);
while(opt--)
{
maxn=0;sum1=sum2=num1=num2=0;
read(n);read(m);S=n*m+1;T=n*m+2;
for(R ll i=1;i<=n;++i)
for(R ll j=1;j<=m;++j)
read(hei[i][j]),maxn=max(maxn,hei[i][j]);
for(R ll i=1;i<=n;++i)
for(R ll j=1;j<=m;++j)
{
bel[i][j]=((i+j)&1);
if(bel[i][j]) num1++,sum1+=hei[i][j];
else num2++,sum2+=hei[i][j];
}
// printf("%lld %lld %lld %lld\n",num1,sum1,num2,sum2);
if(num1==num2) solve_cdy();
else solve_wzy();
}
// fclose(stdin);
// fclose(stdout);
return 0;
}

HEOI 2019 RP++

P5038 [SCOI2012]奇怪的游戏的更多相关文章

  1. [题目] Luogu P5038 [SCOI2012]奇怪的游戏

    学习资料 -----1----- -----2----- P5038 [SCOI2012]奇怪的游戏 一道甚神但没用到高深模型的题 思路 没思路,看题解吧 代码 #include <iostre ...

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

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

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

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

  4. 题解 P5038 [SCOI2012]奇怪的游戏

    题解 题目 做这题之前,做了一道叫星际战争的题,很容易想到二分 \(+\) 网络流,那么二分啥呢? 我们先推一下式子,因为是对相邻格子加数,那么可以联想到黑白染色类问题. 设有黑色格子 \(B\) 个 ...

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

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

  6. Bzoj2756 [SCOI2012]奇怪的游戏

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

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

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

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

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

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

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

随机推荐

  1. 8-matlab-gui-显示图片有坐标刻度问题

    在图片上显示图片时,总是有图片,一遍做法是使得刻度为空就可了: 在你的每一个axes的CreateFcn函数中添加一下代码即可:set(hObject,'xTick',[]);set(hObject, ...

  2. 查询测试程序中的selectOne和selectList函数

    selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常: org.apache.ibatis.exceptions.TooManyResultsException: Expe ...

  3. Java 设计模式系列(十八)备忘录模式(Memento)

    Java 设计模式系列(十八)备忘录模式(Memento) 备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式.备忘录对象是一个用来存储另外一个对象内部状态 ...

  4. An interview question from MicroStrategy

    去年校招时的一道面试题,觉得蛮有意思,贴出来. Question: Spy start at a, during an interval he moves |b| to right when b &g ...

  5. max文件属性设置,

    之前一直都没找到 用到的时候就是用net 弄了.哎.还在开发东西都是在9上面, 这次脚本必须在 max8 上面 逼的我找到了他 getFileAttribute <filename_string ...

  6. C#使用互斥量(Mutex)实现多进程并发操作时多进程间线程同步操作(进程同步)的简单示例代码及使用方法

    本文主要是实现操作系统级别的多进程间线程同步(进程同步)的示例代码及测试结果.代码经过测试,可供参考,也可直接使用. 承接上一篇博客的业务场景[C#使用读写锁三行代码简单解决多线程并发写入文件时线程同 ...

  7. 安装一个Redis

    1. 官网 http://redis.io/ 2.下载 官方不提供windows版本,但https://github.com/MSOpenTech/redis 可以从这里获取64位. 3.

  8. Linux 基础教程 25-命令和文件查找

    which     不管是在Windows还是Linux系统中,我们都会偶尔执行一些系统命令,比如Windows常见的cmd.ping.ipconfig等,它们的位置都在%systemdrive%中. ...

  9. [LeetCode 题解]: Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  10. 一个例子教你理解java回调机制

    网上很多例子都写的很难理解,笔者刚开始都已经弄晕菜了. 这个例子,应该是再简单,再简洁不过的了,例子目的是测试某个方法的执行时间.这里就写三个java类,一个接口,一个实现,还有一个用于测试时间的类. ...