BZOJ 2756 奇怪的游戏(最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2756
题意:在一个 N*M 的棋盘上玩,每个格子有一个数。每次 选择两个相邻的格子,并使这两个数都加上 1。 问最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同一个数则输出-1。
思路:对棋盘进行黑白染色,则每次操作使得黑白两色的格子总和各增加1。设黑色总和s1,个数cnt1;白色总和s2,个数cnt2,设最后的数字为x,那么有:
x*cnt1-s1=x*cnt2-s2。
(1)若cnt1!=cnt2,那么x是唯一的,x=(s1-s2)/(cnt1-cnt2),只要判定这个x是否合法即可;
(2)若cnt1=cnt2,那么x是不唯一的,但是x是单调的,即若x可以,则x+1也可以,因为黑白可以两两配对后各增加1。因此可以二分x,判定是否可行。
现在就是给定x判定是否可行。原点向黑格子连边,白格子向汇点连边,权值都是x-格子的数字。相邻格子连边无穷。满流即可。
struct node { int v,next; i64 cap; }; node edges[N]; int head[N],e; void add(int u,int v,i64 cap) { edges[e].v=v; edges[e].cap=cap; edges[e].next=head[u]; head[u]=e++; } void Add(int u,int v,i64 cap) { add(u,v,cap); add(v,u,0); } int pre[N],h[N],num[N],cur[N]; i64 Maxflow(int s,int t,int n) { int i; for(i=0;i<=n;i++) h[i]=num[i]=0,cur[i]=head[i]; int u=s,v,x; i64 ans=0,Min; while(h[u]<n) { if(u==t) { Min=inf+1; for(i=s;i!=t;i=edges[cur[i]].v) { x=cur[i]; if(edges[x].cap<Min) Min=edges[x].cap,v=i; } ans+=Min; u=v; for(i=s;i!=t;i=edges[cur[i]].v) { x=cur[i]; edges[x].cap-=Min; edges[x^1].cap+=Min; } } for(i=cur[u];i!=-1;i=edges[i].next) { v=edges[i].v; if(edges[i].cap>0&&h[u]==h[v]+1) break; } if(i!=-1) { cur[u]=i; pre[edges[i].v]=u; u=edges[i].v; } else { if(--num[h[u]]==0) break; cur[u]=head[u]; x=n; for(i=head[u];i!=-1;i=edges[i].next) { if(edges[i].cap>0) x=min(x,h[edges[i].v]); } h[u]=x+1; num[x+1]++; if(u!=s) u=pre[u]; } } return ans; } i64 a[55][55]; int n,m,b[55][55],s,t; int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; int check(i64 p) { clr(head,-1); e=0; s=0; t=n*m+1; int i,j,k,x,y; i64 sum=0; FOR1(i,n) FOR1(j,m) { if(p<a[i][j]) return 0; if((i+j)&1) Add(s,b[i][j],p-a[i][j]),sum+=p-a[i][j]; else Add(b[i][j],t,p-a[i][j]); if((i+j)%2==0) continue; FOR0(k,4) { x=i+dx[k]; y=j+dy[k]; if(x>=1&&x<=n&&y>=1&&y<=m) { Add(b[i][j],b[x][y],inf); } } } return Maxflow(s,t,t+1)==sum; } i64 cal() { i64 s1=0,s2=0,cnt1=0,cnt2=0,Max=0,ans; int i,j,k=0; FOR1(i,n) FOR1(j,m) b[i][j]=++k; FOR1(i,n) FOR1(j,m) { upMax(Max,a[i][j]); if((i+j)%2==0) s1+=a[i][j],cnt1++; else s2+=a[i][j],cnt2++; } if(cnt1!=cnt2) { ans=(s1-s2)/(cnt1-cnt2); if(check(ans)) return ans*cnt1-s1; return -1; } if(s1!=s2) return -1; i64 low=Max,high=inf,mid; ans=-1; while(low<=high) { mid=(low+high)>>1; if(check(mid)) ans=mid,high=mid-1; else low=mid+1; } if(ans==-1) return -1; return ans*cnt1-s1; } int main() { rush() { RD(n,m); int i,j; FOR1(i,n) FOR1(j,m) RD(a[i][j]); PR(cal()); } }
BZOJ 2756 奇怪的游戏(最大流)的更多相关文章
- bzoj 2756奇怪的游戏
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MB Description Blinke 最近喜欢上一个奇怪的游戏. 这个游戏 ...
- [BZOJ 2756] 奇怪的游戏
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=2756 Algorithm: 比较新颖的题目 首先发现是对矩阵中相邻两数进行操作 & ...
- BZOJ 2756 SCOI2012 奇怪的游戏 最大流
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2756 Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3352 Solved: 919[Submit][Stat ...
- 【BZOJ-2756】奇怪的游戏 最大流 + 分类讨论 + 二分
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2925 Solved: 792[Submit][Stat ...
- BZOJ2756:[SCOI2012]奇怪的游戏(最大流,二分)
Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...
- BZOJ2756 [SCOI2012]奇怪的游戏 最大流
好久没有写博客了.不过这个博客也没有多少人看 最近在写网络流,为了加深理解,来写一两篇题解. 对整个棋盘进行黑白染色以后可以发现,一次操作就是让二分图的两个点的值分别 \(+1\). 这样,我们就可以 ...
- 【BZOJ】【2756】【SCOI2012】奇怪的游戏
网络流-最大流 这题……建模部分先略过 这道题是会卡时限的T_T俺的Dinic被卡了,在此放几篇很棒的讲网络流算法的文章,至于大家耳熟能详的论文就不放了…… http://www.cppblog.co ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 网络流/二分
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1594 Solved: 396[Submit][Stat ...
随机推荐
- cvWaitKey();
1.函数形式:int cvWaitKey(int delay=0 ): 函数功能:cvWaitKey()函数的功能是不断刷新图像,频率时间为delay,单位为ms. 参数: delay——— ...
- Hadoop之TaskInputOutputContext类
在MapReduce过程中,每一个Job都会被分成若干个task,然后再进行处理.那么Hadoop是怎么将Job分成若干个task,并对其进行跟踪处理的呢?今天我们来看一个*Context类——Tas ...
- ADO.NET中的TransactionScope何时需要启用MSTDC(分布式事务管理)
我们知道在ADO.NET中可以用TransactionScope来将多个SqlConnection(多个数据库连接)执行的Sql语句放入一个事物中提交或取消,但是使用TransactionScope的 ...
- shell expr 文件扩展名判断 整数判断
expr "text.sh" : ".*\.sh" &>/dev/null && echo "yes" ||e ...
- selenium定位失败记录
selenium webdriver定位不到元素的五种原因及解决办法 1.动态id定位不到元素 for example: //WebElement xiexin_element = driver.fi ...
- linux设备驱动归纳总结(三):5.阻塞型IO实现【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-60025.html linux设备驱动归纳总结(三):5.阻塞型IO实现 xxxxxxxxxxxxxx ...
- FTP上传类
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;usi ...
- php单例模式是怎么实现的呢
<?php /** * 设计模式之单例模式 * $_instance必须声明为静态的私有变量 * 构造函数和析构函数必须声明为私有,防止外部程序new * 类从而失去单例模式的意义 * getI ...
- 怎么使用 Laravel 的服务容器来优化读写数据库中的 options关键词
其中我们可以最方便地利用的一个特性就是 Laravel 的服务容器了.在这里我不多赘述 Service Container 是个啥,想了解的可以自行搜索.不想了解的就只要大致知道它是个可以 绑定/取出 ...
- JavaEE基础(十)
1.面向对象(package关键字的概述及作用) A:为什么要有包 将字节码(.class)进行分类存放 包其实就是文件夹 B:包的概述 举例: 学生:增加,删除,修改,查询 老师:增加,删除,修改, ...