[题目] Luogu P5038 [SCOI2012]奇怪的游戏
学习资料
-----1-----
-----2-----
一道甚神但没用到高深模型的题
思路
没思路,看题解吧
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define ll long long
#define point(x, y) ((x - 1) * m + y)
using namespace std;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
const int N = 55, _ = 200005;
const ll inf = 1e16;
int n, m, s, t;
int a[N][N], color[N][N];
ll s1, s2, d1, d2, mx, sum, flow, maxflow;
struct Edge { int Nxt, v; ll flow; } e[_ << 1];
int h[_], p = 1;
void add(int u, int v, ll f) {
e[++p].Nxt = h[u]; e[p].v = v; e[p].flow = f; h[u] = p;
e[++p].Nxt = h[v]; e[p].v = u; e[p].flow = 0; h[v] = p;
}
int d[_];
queue<int> q;
bool bfs() {
memset(d, 0, sizeof(d));
while(!q.empty()) q.pop();
q.push(s); d[s] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = h[u]; i; i = e[i].Nxt)
if(e[i].flow && !d[e[i].v])
{
d[e[i].v] = d[u] + 1;
if(e[i].v == t) return true;
q.push(e[i].v);
}
}
return false;
}
ll dinic(int u, ll flow) {
if(u == t) return flow;
ll rest = flow, k;
for(int i = h[u]; i && rest; i = e[i].Nxt)
if(e[i].flow && d[e[i].v] == d[u] + 1)
{
k = dinic(e[i].v, min(rest, e[i].flow));
if(!k) d[e[i].v] = 0;
e[i].flow -= k;
e[i ^ 1].flow += k;
rest -= k;
}
return flow - rest;
}
bool check(ll x) {
sum = flow = maxflow = 0;
p = 1; memset(h, 0, sizeof(h));
for(int i = 1, tx, ty; i <= n; i++)
for(int j = 1; j <= m; j++)
if(color[i][j] == 0)
for(int k = 0; k < 4; k++)
{
tx = i + dx[k], ty = j + dy[k];
if(tx >= 1 && tx <= n && ty >= 1 && ty <= m)
add(point(i, j), point(tx, ty), inf);
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(color[i][j] == 0)
add(s, point(i, j), x - a[i][j]), sum += x - a[i][j];
else
add(point(i, j), t, x - a[i][j]);
while(bfs())
while(flow = dinic(s, inf)) maxflow += flow;
return sum == maxflow;
}
int main()
{
int T = 0;
scanf("%d", &T);
while(T--)
{
mx = s1 = s2 = d1 = d2 = 0;
scanf("%d%d", &n, &m); s = 0, t = n * m + 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
scanf("%d", &a[i][j]), mx = max(mx, 1LL * a[i][j]);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
color[i][j] = (i + j) & 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(color[i][j] == 0) s1 += a[i][j], d1++;
else s2 += a[i][j], d2++;
if(d1 != d2) {
ll x = (s1 - s2) / (d1 - d2);
if(x >= mx && check(x)) printf("%lld\n", x * d1 - s1);
else printf("-1\n");
}
else {
ll l = mx, r = 1e14, mid = 0, ans = 0;
while(l <= r) {
mid = (l + r) >> 1;
if(check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
if(s1 != s2) printf("-1\n");
else printf("%lld\n", ans * d1 - s1);
}
}
return 0;
}
[题目] Luogu P5038 [SCOI2012]奇怪的游戏的更多相关文章
- P5038 [SCOI2012]奇怪的游戏 二分+网络流
$ \color{#0066ff}{ 题目描述 }$ Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 \(N \times M\) 的棋盘上玩,每个格子有一个数.每次\(Blinker\)会 ...
- P5038 [SCOI2012]奇怪的游戏
题目链接 题意分析 首先我们需要求的是统一以后的值\(x\) 并且一般的棋盘操作我们都需要黑白染色 那么对于棋盘格子是偶数的情况的话 答案是存在单调性的 因为如果统一之后 两两搭配还是可以再加一个的 ...
- 题解 P5038 [SCOI2012]奇怪的游戏
题解 题目 做这题之前,做了一道叫星际战争的题,很容易想到二分 \(+\) 网络流,那么二分啥呢? 我们先推一下式子,因为是对相邻格子加数,那么可以联想到黑白染色类问题. 设有黑色格子 \(B\) 个 ...
- 洛谷$P5038\ [SCOI2012]$奇怪的游戏 二分+网络流
正解:二分+网络流 解题报告: 传送门$QwQ$ 这种什么,"同时增加",长得就挺网络流的$QwQ$?然后看到问至少加多少次,于是考虑加个二分呗?于是就大体确定了做题方向,用的网络 ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 网络流/二分
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1594 Solved: 396[Submit][Stat ...
- bzoj2756: [SCOI2012]奇怪的游戏(网络流+分情况)
2756: [SCOI2012]奇怪的游戏 题目:传送门 题解: 发现做不出来的大难题一点一个网络流 %大佬 首先黑白染色(原来是套路...)染色之后就可以保证每次操作都一定会使黑白各一个各自的值加1 ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3352 Solved: 919[Submit][Stat ...
- Bzoj2756 [SCOI2012]奇怪的游戏
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3220 Solved: 886 Description ...
- bzoj 2756 [SCOI2012]奇怪的游戏 二分+网络流
2756:[SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 4926 Solved: 1362[Submit][Stat ...
随机推荐
- 模拟HTTP协议接收请求并返回信息
private string HttpPost(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)W ...
- 4.数码相框-freetype多行显示,居中显示
本章主要内容如下: 1)多行显示 2)居中显示 在上章3.数码相框-通过freetype库实现矢量显示里,我们使用矢量坐标时,该坐标仅仅在原点位置处,所以文字有可能会超出坐标,如下图所示: 既然超出了 ...
- 用idea搭建SSM项目,原来这么简单
目录 前言 软件环境 创建项目 数据库文件 配置文件 pom.xml log4j.properties jdbc.properties applicationContext.xml spring-mv ...
- Java 基础系列合集
Java基础知识你知道多少? Java特性 Java三大特性:封装,继承,多态 Java 抽象类与接口 Java 浅拷贝和深拷贝 Java static和final Java 内部类.静态内部类.匿名 ...
- vue选中与取消简单实现
<li v-for="(item,index) in assign" :key="index" @click="selected(item)&q ...
- 安装 kubernetes v1.11.1
kubernetes 版本 v1.11.1 系统版本:Centos 7.4 3.10.0-693.el7.x86_64 master: 192.168.0.205 node1: 192.168.0.2 ...
- 安装Vue和创建一个Vue脚手架项目
首先 安装node.js,安装成功可以在控制台输入[node --version ]查看node的版本,因为安装了node会自带npm所以我们可以用 [npm --version]查到npm版本 如 ...
- JS中数组去重的九方法
数组去重方法 方法一:运用set结构特点:存储的数据没有重复的,结果为对象,再用Array.from()转换成数组 var arr = [1,1,2,1,3,4,5] ...
- vue引入bootstrap——webpack
想要在vue中引入bootstrap,引入的时候需要按照如下的步骤进行. 1.引入jquery 2.引入bootstrap 阅读本文前,应该能够搭建环境,使用vue-cli进行项目的创建,可以参考 ...
- mysql从入门到放弃-入门知识介绍
数据库在互联网网站的重要性 简单地说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构来组织和存储的,我们可以通过数据库提供的多种方法来管理数据库里的数据.由于数据库不易扩展,所以,在一个互 ...