bzoj2756: [SCOI2012]奇怪的游戏(网络流+分情况)
2756: [SCOI2012]奇怪的游戏
题目:传送门
题解:
发现做不出来的大难题一点一个网络流
%大佬
首先黑白染色(原来是套路...)染色之后就可以保证每次操作都一定会使黑白各一个各自的值加1
那么我们接着统计一下黑白格子个数cnt1和cnt2,以及各自的权值和sum1和sum2
然后就要分情况讨论了:
1、在cnt1不等于cnt2的情况下
假设有解且最终的数值均为ans,那么不难发现:cnt1*ans-cnt2*ans=sum1-sum2(因为每次操作黑白格子的总和同时加1,所以总和差始终不变)
那就可以直接推导出ans=(sum1-sum2)/(cnt1-cnt2) 那么我们其实就只需要判断一下该值是否合法就OK
2、cnt1=cnt2
若sum1不等于sum2 那么一定输出-1,因为差不变啊,显然(不过好像没有这种点)
若sum1=sum2,那么设最终的数值为ans
如果ans满足答案,那么ans+1也一定满足,显然存在单调性,直接就二分check
判断ans是否合法:st连白点,流量ans-d[i][j];黑点连ed,流量ans-d[i][j];相邻的不同颜色的点相连,流量无限;那么只要看看是否满流就好啊。。。
注意上界有点大...
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define inf 999999999999999999
using namespace std;
typedef long long LL;
struct node
{
int x,y,next,other;LL c;
}a[];int len,last[];
void ins(int x,int y,LL c)
{
LL k1,k2;
k1=++len;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len; k2=++len;
a[len].x=y;a[len].y=x;a[len].c=;
a[len].next=last[y];last[y]=len; a[k1].other=k2;
a[k2].other=k1;
}
int list[],h[],st,ed,head,tail;
bool bt_h()
{
memset(h,,sizeof(h));h[st]=;
list[]=st;head=;tail=;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]== && a[k].c>)
{
h[y]=h[x]+;
list[tail++]=y;
}
}
head++;
}
if(h[ed]>)return true;
return false;
}
LL find_flow(int x,LL flow)
{
if(x==ed)return flow;
LL s=,t;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]==h[x]+ && a[k].c> && s<flow)
{
s+=t=find_flow(y,min(a[k].c,flow-s));
a[k].c-=t;a[a[k].other].c+=t;if(s==flow)break;
}
}
if(s==)h[x]=;
return s;
}
int T;
int n,m;
LL mp[][];int d[][];
bool f[][];//黑false白true染色
const int dx[]={,-,,,};
const int dy[]={,,,-,};
bool check(LL sum)
{
LL ret=;
len=;memset(last,,sizeof(last));st=n*m+,ed=st+;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(f[i][j]==true)ins(st,d[i][j],sum-mp[i][j]),ret+=sum-mp[i][j];
else ins(d[i][j],ed,sum-mp[i][j]);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)if(f[i][j]==true)
for(int k=;k<=;k++)
{
int tx=i+dx[k],ty=j+dy[k];
if(d[tx][ty]!=- && f[i][j]!=f[tx][ty])ins(d[i][j],d[tx][ty],inf);
}
LL ans=;while(bt_h())ans+=find_flow(st,inf);
return ret==ans?true:false;
}
LL sol(LL sum)
{
LL ans=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
ans+=(sum-mp[i][j]);
return ans/2LL;
}
int main()
{
scanf("%d",&T);while(T--)
{
LL cnt1=,cnt2=,sum1=,sum2=,maxx=;
scanf("%d%d",&n,&m);memset(mp,,sizeof(mp));memset(d,-,sizeof(d));memset(f,true,sizeof(f));
int ss=;for(int i=;i<=n;i++)for(int j=;j<=m;j++)d[i][j]=++ss;
for(int i=;i<=n;i++)for(int j=;j<=m;j++)scanf("%lld",&mp[i][j]),sum1+=mp[i][j],maxx=max(maxx,mp[i][j]);
for(int i=;i<=n;i++)
for(int j=i%+;j<=m;j+=)
f[i][j]=false,cnt2++,sum2+=mp[i][j];
sum1-=sum2;cnt1=n*m-cnt2;
if(cnt1==cnt2)
{
if(sum1!=sum2)printf("-1\n");
else
{
LL l=maxx,r=inf,ans=-;
while(l<=r)
{
LL mid=(l+r)/;
//if(mid<maxx)l=mid+1;
if(check(mid))r=mid-,ans=mid;
else l=mid+;
}
if(ans==-)printf("-1\n");
else printf("%lld\n",sol(ans));
}
}
else
{
LL ans=(sum1-sum2)/(cnt1-cnt2);
if(ans<maxx || check(ans)==false)printf("-1\n");
else printf("%lld\n",sol(ans));
}
}
return ;
}
bzoj2756: [SCOI2012]奇怪的游戏(网络流+分情况)的更多相关文章
- 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: 1594 Solved: 396[Submit][Stat ...
- BZOJ2756 [SCOI2012]奇怪的游戏 【网络流 + 二分】
题目 Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 Blinker 想知 ...
- BZOJ2756:[SCOI2012]奇怪的游戏(最大流,二分)
Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...
- BZOJ2756 SCOI2012奇怪的游戏(二分答案+最大流)
由数据范围容易想到网络流.由于操作只是对于棋盘上相邻两格,容易想到给其黑白染色. 假设已经知道最后要变成什么数.那么给黑白点之间连边,其流量则表示同时增加的次数,再用源汇给其限流为需要增加的数即可. ...
- BZOJ2756 [SCOI2012]奇怪的游戏 最大流
好久没有写博客了.不过这个博客也没有多少人看 最近在写网络流,为了加深理解,来写一两篇题解. 对整个棋盘进行黑白染色以后可以发现,一次操作就是让二分图的两个点的值分别 \(+1\). 这样,我们就可以 ...
- 【BZOJ2756】奇怪的游戏(二分,网络流)
[BZOJ2756]奇怪的游戏(二分,网络流) 题面 BZOJ Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blink ...
- bzoj 2756 [SCOI2012]奇怪的游戏 二分+网络流
2756:[SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 4926 Solved: 1362[Submit][Stat ...
- 【BZOJ-2756】奇怪的游戏 最大流 + 分类讨论 + 二分
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2925 Solved: 792[Submit][Stat ...
随机推荐
- 没有被广泛采用的box-sizing属性
在标准盒模型下设置的width和height只是内容的宽和高,但在设置了宽和高的情况下若还要设置border.margin.padding等时,会发生溢出的现象,因此需要将盒模型更改. box-siz ...
- .NET平台开源JSON序列化
转载: http://blog.csdn.net/ddgweb/article/details/39643747 一个简单示例: String str = "{’name’:’cyf’,’i ...
- JQuery事件绑定,bind与on区别
jquery事件绑定bind:向匹配元素添加一个或多个事件处理器 $(selector).bind("click",data,function); live:向当前或未来的匹配元素 ...
- WPF常用资源
Textbox error template<Style x:Key="ControlBaseStyle" TargetType="{x:Type Control} ...
- vue入门--初始化
VUE初始化时,可以用vue init webpack-simple或者vue init webpack.前者是简易版的工程,后者是标准的初始化.工程创建成功后,打开发现两个的目录结构有很大不同.si ...
- js面向对象概念解析
ECMAScript有两种开发模式: 1.函数式(过程化) 2.面向对象(OOP). 面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,ECMAScri ...
- Oracle数据库基础(二)
1.表名命名规则:必须以字母开头,不能超过30个字符,不要有Oracle保留字 2.数据类型 字符型: char :2000个字符 定长 效率高 ...
- function——函数声明头的提升和预解析
函数: 即function语句的集合,就是将多个语句封装到一起: 函数的执行要会自己遍历,遇见函数 a():执行语句,就要移交控制权,函数执行完毕之后,控制权又移交回来了! 函数的参数要罗列在func ...
- E5中遍历数组的方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- hiho 1476 - 矩形计数 容斥
题目链接 如图所示,在由N行M列个单位正方形组成的矩形中,有K个单位正方形是黑色的,其余单位正方形是白色的. 你能统计出一共有多少个不同的子矩形是完全由白色单位正方形组成的吗? ----------- ...