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 ...
随机推荐
- 【翻译自mos文章】 11gR1版本号 asmcmd的新命令--cp、md_backup、md_restore
11gR1版本号 asmcmd的新命令--cp.md_backup.md_restore 參考原文: ASMCMD - New commands in 11gR1 (Doc ID 451900.1) ...
- mysqli简介
mysqli简介 PHP MySQLi 简介 PHP MySQLi = PHP MySQL Improved! MySQLi 函数允许您访问 MySQL 数据库服务器. 注释:MySQLi 扩展被设计 ...
- 机器学习 LR中的参数迭代公式推导——极大似然和梯度下降
Logistic本质上是一个基于条件概率的判别模型(DiscriminativeModel). 函数图像为: 通过sigma函数计算出最终结果,以0.5为分界线,最终结果大于0.5则属于正类(类别值为 ...
- 35.QT蝴蝶飞舞
fly.h #ifndef FLY_H #define FLY_H #include <QObject> #include <QPainter> #include <QG ...
- Extjs 可重用组件开始写 2014 8 23日
今天开始自己去写组件. 这次写组件重点在于参考cfWeb来写出自己的组件. 首先先把结构做出来. 对于这次的自定义组件,现在所做的事情关键在于上面四个文件.于是将上面四个文件贴出来. MyApp.js ...
- <错误>
1. package com.multak.cookaraclient.adapter; import android.content.Context; import android.support. ...
- rem 自适应布局 bootstrap 移动端适配
移动端适配用:rem 自使用布局用:bootstrap
- mongodb主从搭建
#tigergao 官网进行下包,可以下载源码包或者二进制包,本次下载的为二进制包,进行试验. 主服务器搭建: mkdir mongomaster cp mongodb-linux-x86_64-rh ...
- activity工作流学习地址
https://wenku.baidu.com/view/8572153150e2524de4187e5d.html
- Pyhton学习——Day37
# HTML# import socket## def main():# sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# sock. ...