$ \color{#0066ff}{ 题目描述 }$

Blinker最近喜欢上一个奇怪的游戏。

这个游戏在一个 \(N \times M\) 的棋盘上玩,每个格子有一个数。每次\(Blinker\)会选择两个相邻的格子,并使这两个数都加上\(1\)。

现在\(Blinker\)想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同一个数则输出\(-1\)。

\(\color{#0066ff}{输入格式}\)

输入的第一行是一个整数\(T\),表示输入数据有T轮游戏组成。

每轮游戏的第一行有两个整数\(N\)和\(M\), 分别代表棋盘的行数和列数。 接下来有\(N\)行,每行\(M\)个数。

\(\color{#0066ff}{输出格式}\)

对于每个游戏输出最少能使游戏结束的次数,如果永远不能变成同一个数则输出\(-1\)。

\(\color{#0066ff}{输入样例}\)

2
2 2
1 2
2 3
3 3
1 2 3
2 3 4
4 3 2

\(\color{#0066ff}{输出样例}\)

2
-1

\(\color{#0066ff}{数据范围与提示}\)

对于\(30%\)的数据,保证\(T<=10,1<=N,M<=8\)

对于\(100%\)的数据,保证 \(T<=10,1<=N,M<=40\),所有数为正整数且小于\(1000000000\)

\(\color{#0066ff}{题解}\)

对于这种方格图,而且还是相邻的数操作,显然可以考虑黑白染色!

可以发现,每次操作只会同时修改两个颜色不同的位置(显然。。。)

既然最后所有的数相同,不妨假设那个数是x,那么再结合黑白染色,可以得出一个式子(有解的情况下)

\(黑点数量*x-黑点权值和=白点数量*x-白点权值和\),其实就是操作次数相同的等式

观察一下这个式子。。。嗯????xTM能解出来我去,不会就这样水了吧。。。

当然不会,x能解出来当且仅当黑白点数量不同(除数不为0),这样我们就能特判一下得到x

当然x可能不合法,要判一下,判断的方法下面会说

那么接下来就是黑白点相同的情况了

根据上面的式子,这时候如果两个权值和不等,那显然无解

那如果相等呢??如何求解x?

考虑二分答案,但是我们要判断有没有单调性

显然当前的图肯定是一个有偶数点个数的图,如果当前x成立,显然由于图是偶数个点,x+1一定是成立的

反之同理,于是这是有单调性的

然后,二分完x,我们如何判断x是否合法(都黑白染色了当然是网络流)

起点向每个白点连x-权值的边,代表需要几次操作,中间连inf的边,右边同理

当前方案合法当且仅当最大流可以满足所有点, 这也是上面判断x是否合法的方式

#include<bits/stdc++.h>
#define LL long long
LL read() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
template<class T> bool chkmax(T &a, const T &b) { return a < b? a = b, 1 : 0; }
template<class T> bool chkmin(T &a, const T &b) { return b < a? a = b, 1 : 0; }
const int maxn = 5e5 + 10;
const LL inf = 9999999999999LL;
struct node {
LL to, can;
node *nxt, *rev;
node(LL to = 0, LL can = 0, node *nxt = NULL): to(to), can(can), nxt(nxt) { rev = NULL; }
}pool[maxn], *tail, *head[maxn], *cur[maxn];
int dep[maxn], n, m, s, t, mp[66][66];
int rx[] = {1, -1, 0, 0};
int ry[] = {0, 0, 1, -1};
void add(int from, int to, LL can) { head[from] = new(tail++) node(to, can, head[from]); }
void link(int from, int to, LL can) {
add(from, to, can), add(to, from, 0LL);
head[from]->rev = head[to]; head[to]->rev = head[from];
}
bool bfs() {
for(int i = s; i <= t; i++) dep[i] = 0, cur[i] = head[i];
std::queue<int> q;
q.push(s); dep[s] = 1;
while(!q.empty()) {
int tp = q.front(); q.pop();
for(node *i = head[tp]; i; i = i->nxt)
if(!dep[i->to] && i->can)
dep[i->to] = dep[tp] + 1, q.push(i->to);
}
return dep[t];
}
LL dfs(int x, LL change) {
if(x == t || !change) return change;
LL flow = 0, ls;
for(node *&i = cur[x]; i; i = i->nxt)
if(dep[i->to] == dep[x] + 1 && (ls = dfs(i->to, std::min(i->can, change)))) {
flow += ls;
change -= ls;
i->can -= ls;
i->rev->can += ls;
if(!change) break;
}
return flow;
}
LL dinic() {
LL flow = 0;
while(bfs()) flow += dfs(s, inf);
return flow;
}
int id(int x, int y) { return (x - 1) * m + y; }
bool ok(LL mid) {
tail = pool;
s = 0, t = n * m + 1;
for(int i = s; i <= t; i++) head[i] = NULL;
LL now = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
if((i + j) & 1) {
now += mid - mp[i][j], link(s, id(i, j), mid - mp[i][j]);
for(int k = 0; k < 4; k++) {
int xx = i + rx[k];
int yy = j + ry[k];
if(xx >= 1 && xx <= n && yy >= 1 && yy <= m) link(id(i, j), id(xx, yy), inf);
}
}
else link(id(i, j), t, mid - mp[i][j]);
}
return now == dinic();
} int main() {
for(int T = read(); T --> 0;) {
n = read(), m = read();
int maxval = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
chkmax(maxval, mp[i][j] = read());
LL tot0 = 0, tot1 = 0, num0 = 0, num1 = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
if((i + j) & 1) num1++, tot1 += mp[i][j];
else num0++, tot0 += mp[i][j];
}
if(num0 ^ num1) {
LL endval = (tot0 - tot1) / (num0 - num1);
if(endval >= maxval && ok(endval)) printf("%lld\n", endval * num1 - tot1);
else puts("-1");
}
else {
if(tot0 ^ tot1) puts("-1");
else {
LL l = maxval, r = inf >> 1, ans = r;
while(l <= r) {
LL mid = (l + r) >> 1;
if(ok(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%lld\n", ans == inf >> 1? -1 : ans * num1 - tot1);
}
}
}
return 0;
}

P5038 [SCOI2012]奇怪的游戏 二分+网络流的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. P5038 [SCOI2012]奇怪的游戏

    题目链接 题意分析 首先我们需要求的是统一以后的值\(x\) 并且一般的棋盘操作我们都需要黑白染色 那么对于棋盘格子是偶数的情况的话 答案是存在单调性的 因为如果统一之后 两两搭配还是可以再加一个的 ...

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

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

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

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

随机推荐

  1. selenium+jenkins网页自动化测试的构建

    jenkins+selenium可以做到对web自动化的持续集成. Jenkins的基本操作: 一.新建视图及job 新建视图: 新建job: 可以选择构建一个自由风格的软件项目或者复制已有的item ...

  2. CloudStack + KVM + HA

    KVM高可用性CS4.2暂时没有实现 The Linux Kernel Virtual Machine (KVM) is a very popular hypervisor choice amongs ...

  3. SQL Server横向扩展:设计,实现与维护(2)- 分布式分区视图

    为了使得朋友们对分布式分区视图有个概念,也为了方便后面的内容展开,我们先看看下面一个图:     讲述分布式分区视图之前,很有必要将之与我们常常熟悉的分区表和索引进行区别. 首先,分布式分区视图是一个 ...

  4. loadrunner12-错误 -26366: 找不到 web_reg_find 的“Text=19728.00”

    转:检查点(web_reg_find函数详解) LR检查点 设置检查点的目的不只是为了验证我们的脚本没有错误,而更重要的是一个规范问题,如何使得测试结果更具有说服力,因此建议所有的测试脚本中都添加检查 ...

  5. Spring Data JPA初使用 *****重要********

    Spring Data JPA初使用 我们都知道Spring是一个非常优秀的JavaEE整合框架,它尽可能的减少我们开发的工作量和难度. 在持久层的业务逻辑方面,Spring开源组织又给我们带来了同样 ...

  6. bootstrap导航条相关知识

    在导航条(navbar)中有一个背景色.而且导航条可以是纯链接(类似导航),也可以是表单,还有就是表单和导航一起结合等多种形式. 为导航条添加标题.二级菜单及状态 <div class=&quo ...

  7. Word2013文章如何直接发布到CSDN博客

    目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...

  8. Grunt 与WebStrom 集成

    为了不想使用命令行的方式开着grunt,打算将Grunt命令集成WebStrom 中 . 1.将配置好的Gruntfile文件放到项目的根目录下.. 2.File-setting-Extental T ...

  9. 【小梅哥SOPC学习笔记】系统时钟的使用

    给NIOS II CPU添加一颗澎湃的心——系统时钟的使用 本实验介绍如何在Qsys中添加一个定时器作为NIOS II的心跳定时器,并在NIOS II中软件编程使用该定时器. 将上一个实验watchd ...

  10. freePCRF免费版体验

    [摘要]遍寻网络数昼夜,未得开源PCRF,亦未得有参考价值的PCRF相关文档.所幸觅得免费体验版freePCRF软件.可窥见PCRF设计思路.方法:PCC规则定义.管理策略:遂记录安装.体验心得. f ...